/*****************************************************************************
 * Copyright(C)SEGA 1995-1997/SYSTEM R&D DEPT                                *
 *                                                                           *
 * COMMAND :                                                                 *
 *                                                                           *
 * FILE:    NJReadNam.c                                                      *
 *                                                                           *
 * VERSION: 1.00                                                             *
 *                                                                           *
 * DATE: 1997/05/14                                                          *
 *                                                                           *
 *****************************************************************************/
#define __NJVReadNam_c
#include "NJVRead.h"

/*****************************************************************************
 *
 *      local
 *
 *****************************************************************************/
static int alloc_count=0;    /* for debug */
static int free_count=0;     /* for debug */
/*****************************************************************************
 *
 *      Read Nam
 *
 *****************************************************************************/
/*****************************************************************************
 *      Get size
 *****************************************************************************/
int NJV_GetMdataSize(NJV_WorkTab *t_p, FILE *fp)
{
    int done=0;
    int      n;
    do {
        fgets(t_p->buf, NJV_BUFFER_MAX, fp);
        NJV_GetWords(pwl, t_p->buf);
        t_p->current_line++;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            n = 0;
        } else if (!strcmp(pwl->pwords[0], STR_END)) {
            done = 1;   
        } else {
            n++;
        }
    } while(!done && !feof(fp));

#if 0
    fprintf(stderr, "Mdata %d\n", n);
#endif
    return n;
}

int NJV_GetPositionSize(NJV_WorkTab *t_p, FILE *fp)
{
    int done=0;
    int      n;
    do {
        fgets(t_p->buf, NJV_BUFFER_MAX, fp);
        NJV_GetWords(pwl, t_p->buf);
        t_p->current_line++;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            n = 0;
        } else if (!strcmp(pwl->pwords[0], STR_END)) {
            done = 1;   
        } else {
            n++;
        }
    } while(!done && !feof(fp));

#if 0
    fprintf(stderr, "Position %d\n", n);
#endif
    return n;
}

int NJV_GetXrotationSize(NJV_WorkTab *t_p, FILE *fp)
{
    int done=0;
    int      n;
    do {
        fgets(t_p->buf, NJV_BUFFER_MAX, fp);
        NJV_GetWords(pwl, t_p->buf);
        t_p->current_line++;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            n = 0;
        } else if (!strcmp(pwl->pwords[0], STR_END)) {
            done = 1;   
        } else {
            n++;
        }
    } while(!done && !feof(fp));

#if 0
    fprintf(stderr, "Xrotation %d\n", n);
#endif
    return n;
}

int NJV_GetRotationSize(NJV_WorkTab *t_p, FILE *fp)
{
    int done=0;
    int      n;
    do {
        fgets(t_p->buf, NJV_BUFFER_MAX, fp);
        NJV_GetWords(pwl, t_p->buf);
        t_p->current_line++;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            n = 0;
        } else if (!strcmp(pwl->pwords[0], STR_END)) {
            done = 1;   
        } else {
            n++;
        }
    } while(!done && !feof(fp));

#if 0
    fprintf(stderr, "Rotation %d\n", n);
#endif
    return n;
}

int NJV_GetScaleSize(NJV_WorkTab *t_p, FILE *fp)
{
    int done=0;
    int      n;
    do {
        fgets(t_p->buf, NJV_BUFFER_MAX, fp);
        NJV_GetWords(pwl, t_p->buf);
        t_p->current_line++;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            n = 0;
        } else if (!strcmp(pwl->pwords[0], STR_END)) {
            done = 1;   
        } else {
            n++;
        }
    } while(!done && !feof(fp));

#if 0
    fprintf(stderr, "Scale %d\n", n);
#endif
    return n;
}

int NJV_GetAxevectSize(NJV_WorkTab *t_p, FILE *fp)
{
    int done=0;
    int      n;
    do {
        fgets(t_p->buf, NJV_BUFFER_MAX, fp);
        NJV_GetWords(pwl, t_p->buf);
        t_p->current_line++;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            n = 0;
        } else if (!strcmp(pwl->pwords[0], STR_END)) {
            done = 1;   
        } else {
            n++;
        }
    } while(!done && !feof(fp));

#if 0
    fprintf(stderr, "Axevect %d\n", n);
#endif
    return n;
}

int NJV_GetPointerSize(NJV_WorkTab *t_p, FILE *fp)
{
    int done=0;
    int      n;
    do {
        fgets(t_p->buf, NJV_BUFFER_MAX, fp);
        NJV_GetWords(pwl, t_p->buf);
        t_p->current_line++;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            n = 0;
        } else if (!strcmp(pwl->pwords[0], STR_END)) {
            done = 1;   
        } else {
            n++;
        }
    } while(!done && !feof(fp));

#if 0
    fprintf(stderr, "Pointer %d\n", n);
#endif
    return n;
}

/*****************************************************************************
 *      Dispatch rutines
 *****************************************************************************/
/*--------------*/
/* local macros */
/*--------------*/
#define _FGET     fgets(t_p->buf, NJV_BUFFER_MAX, fp) /* read a line     */
#define _GETW     NJV_GetWords(pwl, t_p->buf)         /* get args        */
#define _CHK(_n)  NJV_WORD_N_CHECK(pwl, _n)           /* check count     */
#define _CLP      t_p->current_line++                 /* inc currentline */
/*++*/

/*
 * ssn_ReadPOSITION
 */
static int ssn_ReadPOSITION(FILE *fp, NJV_WorkTab *t_p)
{
    int        done = 0;
    char       *name_p = t_p->position_list[t_p->position_n].name;
    NJS_MKEY_F *tmp_p = t_p->position_list[t_p->position_n++].data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadPOSITION\n");
#endif

    _CHK(2); _CLP;
    strcpy(name_p, pwl->pwords[1]);
    do {
        _FGET; _GETW; _CLP;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            do {
                _FGET; _GETW;
                if (!strcmp(pwl->pwords[0], STR_END)) {
                    _CLP;
                    done = 1;
                } else {
                    _CHK(5); _CLP;
                    tmp_p->keyframe = NJV_ATOI(pwl->pwords[1]);
                    tmp_p->key[0]   = NJV_ATOF(pwl->pwords[2]);
                    tmp_p->key[1]   = NJV_ATOF(pwl->pwords[3]);
                    tmp_p->key[2]   = NJV_ATOF(pwl->pwords[4]);
                    tmp_p++;
                }
            } while (!done);
        }
    } while (!done);

    return TRUE;
}

/*
 * ssn_ReadROTATION
 */
static int ssn_ReadROTATION(FILE *fp, NJV_WorkTab *t_p)
{
    int        done = 0;
    char       *name_p = t_p->rotation_list[t_p->rotation_n].name;
    NJS_MKEY_A *tmp_p = t_p->rotation_list[t_p->rotation_n++].data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadROTATION\n");
#endif

    _CHK(2); _CLP;
    strcpy(name_p, pwl->pwords[1]);
    do {
        _FGET; _GETW; _CLP;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            do {
                _FGET; _GETW;
                if (!strcmp(pwl->pwords[0], STR_END)) {
                    _CLP;
                    done = 1;
                } else {
                    _CHK(5); _CLP;
                    tmp_p->keyframe = NJV_ATOI(pwl->pwords[1]);
					tmp_p->key[0] = (((Sint32)(((NJV_ATOF(pwl->pwords[2])) * 65536.0) / 360.0)) & 0x0000ffff);
                    tmp_p->key[1] = (((Sint32)(((NJV_ATOF(pwl->pwords[3])) * 65536.0) / 360.0)) & 0x0000ffff);
                    tmp_p->key[2] = (((Sint32)(((NJV_ATOF(pwl->pwords[4])) * 65536.0) / 360.0)) & 0x0000ffff);
                    tmp_p++;
                }
            } while (!done);
        }
    } while (!done);

    return TRUE;
}

/*
 * ssn_ReadSCALE
 */
static int ssn_ReadSCALE(FILE *fp, NJV_WorkTab *t_p)
{
    int        done = 0;
    char       *name_p = t_p->scale_list[t_p->scale_n].name;
    NJS_MKEY_F *tmp_p = t_p->scale_list[t_p->scale_n++].data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadSCALE\n");
#endif

    _CHK(2); _CLP;
    strcpy(name_p, pwl->pwords[1]);
    do {
        _FGET; _GETW; _CLP;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            do {
                _FGET; _GETW;
                if (!strcmp(pwl->pwords[0], STR_END)) {
                    _CLP;
                    done = 1;
                } else {
                    _CHK(5); _CLP;
                    tmp_p->keyframe = NJV_ATOI(pwl->pwords[1]);
                    tmp_p->key[0]   = NJV_ATOF(pwl->pwords[2]);
                    tmp_p->key[1]   = NJV_ATOF(pwl->pwords[3]);
                    tmp_p->key[2]   = NJV_ATOF(pwl->pwords[4]);
                    tmp_p++;
                }
            } while (!done);
        }
    } while (!done);

    return TRUE;
}

/*
 * ssn_ReadAXEVCT
 */
static int ssn_ReadAXEVECT(FILE *fp, NJV_WorkTab *t_p)
{
    int        done = 0;
    char       *name_p = t_p->axevct_list[t_p->axevct_n].name;
    NJS_MKEY_F *tmp_p = t_p->axevct_list[t_p->axevct_n++].data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadAXEVCT\n");
#endif

    _CHK(2); _CLP;
    strcpy(name_p, pwl->pwords[1]);
    do {
        _FGET; _GETW; _CLP;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            do {
                _FGET; _GETW;
                if (!strcmp(pwl->pwords[0], STR_END)) {
                    _CLP;
                    done = 1;
                } else {
                    _CHK(5); _CLP;
                    tmp_p->keyframe = NJV_ATOI(pwl->pwords[1]);
                    tmp_p->key[0]   = NJV_ATOF(pwl->pwords[2]);
                    tmp_p->key[1]   = NJV_ATOF(pwl->pwords[3]);
                    tmp_p->key[2]   = NJV_ATOF(pwl->pwords[4]);
                    tmp_p++;
                }
            } while (!done);
        }
    } while (!done);

    return TRUE;
}

/*
 * ssn_ReadXROTATION
 */
static int ssn_ReadXROTATION(FILE *fp, NJV_WorkTab *t_p)
{
    int        done = 0;
    char       *name_p = t_p->xrotation_list[t_p->xrotation_n].name;
    NJS_MKEY_AX *tmp_p = t_p->xrotation_list[t_p->xrotation_n++].data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadXROTATION\n");
#endif

    _CHK(2); _CLP;
    strcpy(name_p, pwl->pwords[1]);
    do {
        _FGET; _GETW; _CLP;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            do {
                _FGET; _GETW;
                if (!strcmp(pwl->pwords[0], STR_END)) {
                    _CLP;
                    done = 1;
                } else {
                    _CHK(6); _CLP;
                    tmp_p->keyframe = NJV_ATOI(pwl->pwords[1]);
                    tmp_p->angle    = (((Sint32)(((NJV_ATOF(pwl->pwords[2])) * 65536.0) / 360.0)) & 0x0000ffff);
                    tmp_p->axe[0]   = NJV_ATOF(pwl->pwords[3]);
                    tmp_p->axe[1]   = NJV_ATOF(pwl->pwords[4]);
                    tmp_p->axe[2]   = NJV_ATOF(pwl->pwords[5]);
                    tmp_p++;
                }
            } while (!done);
        }
    } while (!done);

    return TRUE;
}

/*
 * ssn_ReadPOINTER			 shape 
 */
static int ssn_ReadPOINTER(FILE *fp, NJV_WorkTab *t_p)
{
    int				done = 0;
    char			*name_p = t_p->pointer_list[t_p->pointer_n].name;
	NJV_WorkMKEY_P	*work_p = &t_p->pointer_list[t_p->pointer_n];
    NJS_MKEY_P		*tmp_p = t_p->pointer_list[t_p->pointer_n].data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadPOINTER\n");
#endif

    _CHK(2); _CLP;
    strcpy(name_p, pwl->pwords[1]);
    do {
        _FGET; _GETW; _CLP;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            do {
                _FGET; _GETW;
                if (!strcmp(pwl->pwords[0], STR_END)) {
                    _CLP;
                    done = 1;
                } else {
                    _CHK(3); _CLP;
                    tmp_p->keyframe = NJV_ATOI(pwl->pwords[1]);
                    strcpy(work_p->keyname, pwl->pwords[2]);
					work_p++;
                    tmp_p++;
					t_p->pointer_n++;
                }
            } while (!done);
        }
    } while (!done);

    return TRUE;
}

/*
 * ssn_ReadMDATA1
 */
static int ssn_ReadMDATA1(FILE *fp, NJV_WorkTab *t_p)
{
    int        done = 0;
	char           *name_p = t_p->mdata1_list[t_p->mdata1_n].name;
    NJV_WorkMDATA1 *work_p = &t_p->mdata1_list[t_p->mdata1_n];
    NJS_MDATA1     *tmp_p  = t_p->mdata1_list[t_p->mdata1_n++].data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadMDATA1\n");
#endif

    _CHK(2); _CLP;
    strcpy(name_p, pwl->pwords[1]);
    do {
        _FGET; _GETW; _CLP;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            do {
                _FGET; _GETW;
                if (!strcmp(pwl->pwords[0], STR_END)) {
                    _CLP;
                    done = 1;
                } else {
                    _CHK(2); _CLP;
                    strcpy(work_p->pname[0], pwl->pwords[0]);
                    tmp_p->nb[0]   = NJV_ATOI(pwl->pwords[1]);
					work_p++;
                    tmp_p++;
                }
            } while (!done);
        }
    } while (!done);

    return TRUE;
}

/*
 * ssn_ReadMDATA2
 */
static int ssn_ReadMDATA2(FILE *fp, NJV_WorkTab *t_p)
{
    int        done = 0;
	char           *name_p = t_p->mdata2_list[t_p->mdata2_n].name;
    NJV_WorkMDATA2 *work_p = &t_p->mdata2_list[t_p->mdata2_n];
    NJS_MDATA2     *tmp_p  = t_p->mdata2_list[t_p->mdata2_n++].data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadMDATA2\n");
#endif

    _CHK(2); _CLP;
    strcpy(name_p, pwl->pwords[1]);
    do {
        _FGET; _GETW; _CLP;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            do {
                _FGET; _GETW;
                if (!strcmp(pwl->pwords[0], STR_END)) {
                    _CLP;
                    done = 1;
                } else {
                    _CHK(4); _CLP;
                    strcpy(work_p->pname[0], pwl->pwords[0]);
                    strcpy(work_p->pname[1], pwl->pwords[1]);
                    tmp_p->nb[0]   = NJV_ATOI(pwl->pwords[2]);
                    tmp_p->nb[1]   = NJV_ATOI(pwl->pwords[3]);
					work_p++;
                    tmp_p++;
                }
            } while (!done);
        }
    } while (!done);

    return TRUE;
}

/*
 * ssn_ReadMDATA3
 */
static int ssn_ReadMDATA3(FILE *fp, NJV_WorkTab *t_p)
{
    int        done = 0;
	char           *name_p = t_p->mdata3_list[t_p->mdata3_n].name;
    NJV_WorkMDATA3 *work_p = &t_p->mdata3_list[t_p->mdata3_n];
    NJS_MDATA3     *tmp_p  = t_p->mdata3_list[t_p->mdata3_n++].data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadMDATA3\n");
#endif

    _CHK(2); _CLP;
    strcpy(name_p, pwl->pwords[1]);
    do {
        _FGET; _GETW; _CLP;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            do {
                _FGET; _GETW;
                if (!strcmp(pwl->pwords[0], STR_END)) {
                    _CLP;
                    done = 1;
                } else {
                    _CHK(6); _CLP;
                    strcpy(work_p->pname[0], pwl->pwords[0]);
                    strcpy(work_p->pname[1], pwl->pwords[1]);
                    strcpy(work_p->pname[2], pwl->pwords[2]);
                    tmp_p->nb[0]   = NJV_ATOI(pwl->pwords[3]);
                    tmp_p->nb[1]   = NJV_ATOI(pwl->pwords[4]);
                    tmp_p->nb[2]   = NJV_ATOI(pwl->pwords[5]);
					work_p++;
                    tmp_p++;
                }
            } while (!done);
        }
    } while (!done);

    return TRUE;
}

/*
 * ssn_ReadMDATA4
 */
static int ssn_ReadMDATA4(FILE *fp, NJV_WorkTab *t_p)
{
    int        done = 0;
	char           *name_p = t_p->mdata4_list[t_p->mdata4_n].name;
    NJV_WorkMDATA4 *work_p = &t_p->mdata4_list[t_p->mdata4_n];
    NJS_MDATA4     *tmp_p  = t_p->mdata4_list[t_p->mdata4_n++].data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadMDATA4\n");
#endif

    _CHK(2); _CLP;
    strcpy(name_p, pwl->pwords[1]);
    do {
        _FGET; _GETW; _CLP;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            do {
                _FGET; _GETW;
                if (!strcmp(pwl->pwords[0], STR_END)) {
                    _CLP;
                    done = 1;
                } else {
                    _CHK(8); _CLP;
                    strcpy(work_p->pname[0], pwl->pwords[0]);
                    strcpy(work_p->pname[1], pwl->pwords[1]);
                    strcpy(work_p->pname[2], pwl->pwords[2]);
                    strcpy(work_p->pname[3], pwl->pwords[3]);
                    tmp_p->nb[0]   = NJV_ATOI(pwl->pwords[4]);
                    tmp_p->nb[1]   = NJV_ATOI(pwl->pwords[5]);
                    tmp_p->nb[2]   = NJV_ATOI(pwl->pwords[6]);
                    tmp_p->nb[3]   = NJV_ATOI(pwl->pwords[7]);
					work_p++;
                    tmp_p++;
                }
            } while (!done);
        }
    } while (!done);

    return TRUE;
}


/*
 * ssn_ReadMOTION
 */
static int ssn_ReadMOTION(FILE *fp, NJV_WorkTab *t_p)
{
    int            done=0;
    NJV_WorkMOTION *work_p = &t_p->motion_list[t_p->motion_n++];
    NJS_MOTION     *tmp_p = work_p->data_p;
	char           *stopstring;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadMOTION\n");
#endif

    _CHK(2); _CLP;
    strcpy(work_p->name, pwl->pwords[1]);
    
    do {
        _FGET; _GETW; _CLP;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            _FGET; _GETW; _CHK(2); _CLP;            /* mdata       */
            strcpy(work_p->mdataname, pwl->pwords[1]);
            _FGET; _GETW; _CHK(2); _CLP;            /* nbFrame     */
            tmp_p->nbFrame = NJV_ATOI(pwl->pwords[1]);
            _FGET; _GETW; _CHK(2); _CLP;            /* type        */
            tmp_p->type = (Uint8)NJV_STRTOL(pwl->pwords[1], &stopstring, 16);
			_FGET; _GETW; _CHK(2); _CLP;            /* inp_f        */
			if( pwl->pwords[1][0] == '0' && pwl->pwords[1][1] == 'x' )
				tmp_p->inp_fn = (Uint8)NJV_STRTOL(pwl->pwords[1], &stopstring, 16);
			else
				tmp_p->inp_fn = NJV_ATOI(pwl->pwords[1]);

        } else if (!strcmp(pwl->pwords[0], STR_END)) {
            done = 1;
        }
    } while (!done);
    
    return TRUE;
}

/*
 * ssn_ReadACTION
 */
static int ssn_ReadACTION(FILE *fp, NJV_WorkTab *t_p)
{
    int            done=0;
    NJV_WorkACTION *work_p = &t_p->action_list[t_p->action_n++];
    NJS_ACTION     *tmp_p = work_p->data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadACTION\n");
#endif

    _CHK(2); _CLP;
    strcpy(work_p->name, pwl->pwords[1]);
    
    do {
        _FGET; _GETW; _CLP;
        if (!strcmp(pwl->pwords[0], STR_START)) {
            _FGET; _GETW; _CHK(2); _CLP;            /* object       */
            strcpy(work_p->objectname, pwl->pwords[1]);
            _FGET; _GETW; _CHK(2); _CLP;            /* motion       */
            strcpy(work_p->motionname, pwl->pwords[1]);
        } else if (!strcmp(pwl->pwords[0], STR_END)) {
            done = 1;
        }
    } while (!done);
    
    return TRUE;
}

/*
 * Callback Table
 */
#define CMD_ENT(_name)	ssn_Read##_name, STR_##_name
static NJV_ReadCmd cmdtab[] = {
        CMD_ENT(POSITION),
        CMD_ENT(XROTATION),
        CMD_ENT(ROTATION),
        CMD_ENT(SCALE),
        CMD_ENT(AXEVECT),
        CMD_ENT(POINTER),		/* shape */
        CMD_ENT(POINT),
        CMD_ENT(NORMAL),
        CMD_ENT(MDATA1),
        CMD_ENT(MDATA2),
        CMD_ENT(MDATA3),
        CMD_ENT(MDATA4),
        CMD_ENT(MOTION),
        CMD_ENT(ACTION),
    };
static int cmdn = sizeof(cmdtab) / sizeof(NJV_ReadCmd);

/*****************************************************************************
 *      read nja (model and texture)
 *****************************************************************************/
/*
 * NJV_ReadNam
 */
int NJV_ReadNam(
NJV_Nja *nja_p,
char *filename,
int mode )			/* NJV_MODE_NAM or NJV_MODE_NAS */
{
    int                     i, j;
    FILE                     *fp;
    NJV_WorkTab tab, *t_p = &tab;
    char              *tmpname_p;   
	NJS_MDATA1 *mdata1_p;
	NJS_MDATA2 *mdata2_p;
	NJS_MDATA3 *mdata3_p;
	NJS_MDATA4 *mdata4_p;
	NJS_MKEY_P *mkey_p_p;

    /*----------------*
     *     init       *
     *----------------*/
	pwl = &wl;
    NJV_GetWordsInit(pwl);
    NJV_MallocInit(t_p);

    /* work */
    t_p->position_n     = 0;
    t_p->position_list  = (NJV_WorkMKEY_F *)NULL;
    t_p->rotation_n     = 0;
    t_p->rotation_list  = (NJV_WorkMKEY_A *)NULL;
    t_p->scale_n        = 0;
    t_p->scale_list     = (NJV_WorkMKEY_F *)NULL;
    t_p->axevct_n      = 0;
    t_p->axevct_list   = (NJV_WorkMKEY_F *)NULL;
    t_p->xrotation_n    = 0;
    t_p->xrotation_list = (NJV_WorkMKEY_AX *)NULL;
    t_p->pointer_n       = 0;
    t_p->pointer_list    = (NJV_WorkMKEY_P *)NULL;
    t_p->point_n         = 0;						/* shape */
    t_p->point_list      = (NJV_WorkPoint *)NULL;
    t_p->normal_n        = 0;
    t_p->normal_list     = (NJV_WorkNormal *)NULL;

    t_p->mdata1_n       = 0;
    t_p->mdata1_list	= (NJV_WorkMDATA1 *)NULL;
    t_p->mdata2_n		= 0;
    t_p->mdata2_list	= (NJV_WorkMDATA2 *)NULL;
    t_p->mdata3_n		= 0;
    t_p->mdata3_list	= (NJV_WorkMDATA3 *)NULL;
    t_p->mdata4_n		= 0;
    t_p->mdata4_list	= (NJV_WorkMDATA4 *)NULL;
    t_p->motion_n		= 0;
    t_p->motion_list	= (NJV_WorkMOTION *)NULL;
    t_p->action_n		= 0;
    t_p->action_list	= (NJV_WorkACTION *)NULL;

    t_p->current_line    = 0;

    /* output */
    nja_p->action.object = (NJS_OBJECT *)NULL;  /* not support now */

    /*----------------*
     * file open      *
     *----------------*/
    if (!(fp = fopen(filename, "r"))) {
        fprintf(stderr, "Error : Can't open %s\n", filename);
        return FALSE;
    }
    t_p->filename = NJV_Strdup(t_p, filename);

    /*-----------------*
     * phase 1 : count *
     *-----------------*/
	t_p->object_tree_n = 0;
	t_p->pointer_total_n = 0;
    rewind(fp);
    t_p->current_line = 0;
    /* count elements */
    do {
        fgets(t_p->buf, NJV_BUFFER_MAX, fp);
        NJV_GetWords(pwl, t_p->buf);
        t_p->current_line++;
        if (!strcmp(pwl->pwords[0], STR_POSITION)) {
            t_p->position_n++;
        } else if (!strcmp(pwl->pwords[0], STR_ROTATION)) {
            t_p->rotation_n++;
        } else if (!strcmp(pwl->pwords[0], STR_SCALE)) {
            t_p->scale_n++;
        } else if (!strcmp(pwl->pwords[0], STR_AXEVECT)) {
            t_p->axevct_n++;
        } else if (!strcmp(pwl->pwords[0], STR_XROTATION)) {
            t_p->xrotation_n++;
        } else if (!strcmp(pwl->pwords[0], STR_POINT)) {	/* shape */
            t_p->point_n++;
        } else if (!strcmp(pwl->pwords[0], STR_NORMAL)) {
            t_p->normal_n++;
        } else if (!strcmp(pwl->pwords[0], STR_POINTER)) {
            t_p->pointer_n++;
            t_p->pointer_total_n += NJV_GetPointerSize(t_p, fp);
        } else if (!strcmp(pwl->pwords[0], STR_MDATA1)) {
            t_p->mdata1_n++;
            t_p->object_tree_n += NJV_GetMdataSize(t_p, fp);
        } else if (!strcmp(pwl->pwords[0], STR_MDATA2)) {
            t_p->mdata2_n++;
            t_p->object_tree_n += NJV_GetMdataSize(t_p, fp);
        } else if (!strcmp(pwl->pwords[0], STR_MDATA3)) {
            t_p->mdata3_n++;
            t_p->object_tree_n += NJV_GetMdataSize(t_p, fp);
        } else if (!strcmp(pwl->pwords[0], STR_MDATA4)) {
            t_p->mdata4_n++;
            t_p->object_tree_n += NJV_GetMdataSize(t_p, fp);
        } else if (!strcmp(pwl->pwords[0], STR_MOTION)) {
            t_p->motion_n++;
        } else if (!strcmp(pwl->pwords[0], STR_ACTION)) {
            t_p->action_n++;
		}
    } while(!feof(fp));

#if 0
    fprintf(stderr, "position_n %d\n", t_p->position_n);
    fprintf(stderr, "rotation_n %d\n", t_p->rotation_n);
    fprintf(stderr, "scale_n %d\n", t_p->scale_n);
    fprintf(stderr, "axevct_n %d\n", t_p->axevct_n);
    fprintf(stderr, "xrotation_n %d\n", t_p->xrotation_n);
    fprintf(stderr, "point_n %d\n", t_p->point_n);
    fprintf(stderr, "normal_n %d\n", t_p->normal_n);
    fprintf(stderr, "mdata1_n %d\n", t_p->mdata1_n);
    fprintf(stderr, "mdata2_n %d\n", t_p->mdata2_n);
    fprintf(stderr, "mdata3_n %d\n", t_p->mdata3_n);
    fprintf(stderr, "mdata4_n %d\n", t_p->mdata4_n);
    fprintf(stderr, "motion_n  %d\n", t_p->motion_n);
    fprintf(stderr, "action_n  %d\n", t_p->action_n);
#endif

    /* malloc workbuf */
    if (t_p->position_n > 0) {
        NJV_MCHECK(t_p->position_list, (NJV_WorkMKEY_F *)NJV_Malloc(t_p,
            sizeof(NJV_WorkMKEY_F)*t_p->position_n, "position_n"));
    }

    if (t_p->rotation_n > 0) {
        NJV_MCHECK(t_p->rotation_list, (NJV_WorkMKEY_A *)NJV_Malloc(t_p,
            sizeof(NJV_WorkMKEY_A)*t_p->rotation_n, "rotation_n"));
    }

    if (t_p->scale_n > 0) {
        NJV_MCHECK(t_p->scale_list, (NJV_WorkMKEY_F *)NJV_Malloc(t_p,
            sizeof(NJV_WorkMKEY_F)*t_p->scale_n, "scale_n"));
    }

    if (t_p->axevct_n > 0) {
        NJV_MCHECK(t_p->axevct_list, (NJV_WorkMKEY_F *)NJV_Malloc(t_p,
            sizeof(NJV_WorkMKEY_F)*t_p->axevct_n, "axevct_n"));
    }

    if (t_p->xrotation_n > 0) {
        NJV_MCHECK(t_p->xrotation_list, (NJV_WorkMKEY_AX *)NJV_Malloc(t_p,
            sizeof(NJV_WorkMKEY_AX)*t_p->xrotation_n, "xrotation_n"));
    }

    if (t_p->pointer_n > 0) {
        NJV_MCHECK(t_p->pointer_list, (NJV_WorkMKEY_P *)NJV_Malloc(t_p,
            sizeof(NJV_WorkMKEY_P)*t_p->pointer_total_n, "pointer_n"));
    }

    if (t_p->point_n > 0) {
        NJV_MCHECK(t_p->point_list, (NJV_WorkPoint *)NJV_Malloc(t_p,
            sizeof(NJV_WorkPoint)*t_p->point_n, "point_n"));
    }

    if (t_p->normal_n > 0) {
        NJV_MCHECK(t_p->normal_list, (NJV_WorkNormal *)NJV_Malloc(t_p,
            sizeof(NJV_WorkNormal)*t_p->normal_n, "normal_n"));
    }

	if (t_p->mdata1_n > 0) {
        NJV_MCHECK(t_p->mdata1_list, (NJV_WorkMDATA1 *)NJV_Malloc(t_p,
            sizeof(NJV_WorkMDATA1)*t_p->object_tree_n, "mdata1_n"));
    }

    if (t_p->mdata2_n > 0) {
        NJV_MCHECK(t_p->mdata2_list, (NJV_WorkMDATA2 *)NJV_Malloc(t_p,
            sizeof(NJV_WorkMDATA2)*t_p->object_tree_n, "mdata2_n"));
    }

    if (t_p->mdata3_n > 0) {
        NJV_MCHECK(t_p->mdata3_list, (NJV_WorkMDATA3 *)NJV_Malloc(t_p,
            sizeof(NJV_WorkMDATA3)*t_p->object_tree_n, "mdata3_n"));
    }

    if (t_p->mdata4_n > 0) {
        NJV_MCHECK(t_p->mdata4_list, (NJV_WorkMDATA4 *)NJV_Malloc(t_p,
            sizeof(NJV_WorkMDATA4)*t_p->object_tree_n, "mdata4_n"));
    }

    if (t_p->motion_n > 0) {
        NJV_MCHECK(t_p->motion_list, (NJV_WorkMOTION *)NJV_Malloc(t_p,
            sizeof(NJV_WorkMOTION)*t_p->motion_n, "motion_n"));
    }

    if (t_p->action_n > 0) {
        NJV_MCHECK(t_p->action_list, (NJV_WorkACTION *)NJV_Malloc(t_p,
            sizeof(NJV_WorkACTION)*t_p->action_n, "action_n"));
    }

    /*------------------*
     * phase 2 : malloc *
     *------------------*/
    /* rewind */
    rewind(fp);
    t_p->current_line = 0;

    /* get mesh list size, point list size, normal list size */
    t_p->position_n  = 0;
    t_p->xrotation_n = 0;
    t_p->rotation_n  = 0;
    t_p->scale_n     = 0;
    t_p->axevct_n    = 0;
    t_p->point_n     = 0;
    t_p->normal_n    = 0;

	do {
        fgets(t_p->buf, NJV_BUFFER_MAX, fp);
        NJV_GetWords(pwl, t_p->buf);
        t_p->current_line++;
        if (!strcmp(pwl->pwords[0], STR_POSITION)) {
            t_p->position_list[t_p->position_n].n = NJV_GetPositionSize(t_p, fp);
            t_p->position_n++;
        } else if (!strcmp(pwl->pwords[0], STR_ROTATION)) {
            t_p->rotation_list[t_p->rotation_n].n = NJV_GetRotationSize(t_p, fp);
            t_p->rotation_n++;
        } else if (!strcmp(pwl->pwords[0], STR_SCALE)) {
            t_p->scale_list[t_p->scale_n].n = NJV_GetScaleSize(t_p, fp);
            t_p->scale_n++;
        } else if (!strcmp(pwl->pwords[0], STR_AXEVECT)) {
            t_p->axevct_list[t_p->axevct_n].n = NJV_GetAxevectSize(t_p, fp);
            t_p->axevct_n++;
        } else if (!strcmp(pwl->pwords[0], STR_XROTATION)) {
            t_p->xrotation_list[t_p->xrotation_n].n = NJV_GetXrotationSize(t_p, fp);
            t_p->xrotation_n++;
        } else if (!strcmp(pwl->pwords[0], STR_NORMAL)) {		/* shape */
            t_p->normal_list[t_p->normal_n].n = NJV_GetNormalSize(t_p, fp);
            t_p->normal_n++;
        } else if (!strcmp(pwl->pwords[0], STR_POINT)) {
            t_p->point_list[t_p->point_n].n = NJV_GetPointSize(t_p, fp);
            t_p->point_n++;
        }

    } while(!feof(fp));

    /* malloc output data */

    /* position list
     * -- malloc count : mesh_n
     */
    for (i=0; i<t_p->position_n; i++) {
        NJV_MCHECK2(t_p->position_list[i].data_p,
          NJS_MKEY_F *, sizeof(NJS_MKEY_F) * t_p->position_list[i].n, "position");
    }

    /* rotation list
     * -- malloc count : rotation_n
     */
    for (i=0; i<t_p->rotation_n; i++) {
        NJV_MCHECK2(t_p->rotation_list[i].data_p, NJS_MKEY_A *,
        sizeof(NJS_MKEY_A) * t_p->rotation_list[i].n, "rotation");
    }

    /* scale list
     * -- malloc count : scale_n
     */
    for (i=0; i<t_p->scale_n; i++) {
        NJV_MCHECK2(t_p->scale_list[i].data_p, NJS_MKEY_F *,
        sizeof(NJS_MKEY_F) * t_p->scale_list[i].n, "scale");
    }

    /* axevect list
     * -- malloc count : axevect_n
     */
    for (i=0; i<t_p->axevct_n; i++) {
        NJV_MCHECK2(t_p->axevct_list[i].data_p, NJS_MKEY_F *,
        sizeof(NJS_MKEY_F) * t_p->axevct_list[i].n, "axevct");
    }

    /* xrotation list
     * -- malloc count : xrotation_n
     */
    for (i=0; i<t_p->xrotation_n; i++) {
        NJV_MCHECK2(t_p->xrotation_list[i].data_p, NJS_MKEY_AX *,
        sizeof(NJS_MKEY_AX) * t_p->xrotation_list[i].n, "xrotation");
    }

    /* pointer list
     * -- malloc count : pointer_n
     */
	if( t_p->pointer_n > 0 ){
		NJV_MCHECK2(mkey_p_p, NJS_MKEY_P *,
		sizeof(NJS_MKEY_P) * t_p->pointer_total_n, "pointer");
	    for (i=0; i<t_p->pointer_total_n; i++) {
	        t_p->pointer_list[i].data_p = &mkey_p_p[i];
	        t_p->pointer_list[i].name[0] = (char)NULL;
		}
    }

    /* points list						shape
     * -- malloc count : point_n
     */
    for (i=0; i<t_p->point_n; i++) {
        NJV_MCHECK2(t_p->point_list[i].data_p,
          NJS_POINT3 *, sizeof(NJS_POINT3) * t_p->point_list[i].n, "points");
    }

    /* normals list
     * -- malloc count : normal_n
     */
    for (i=0; i<t_p->normal_n; i++) {
        NJV_MCHECK2(t_p->normal_list[i].data_p,
          NJS_VECTOR *, sizeof(NJS_VECTOR) * t_p->normal_list[i].n, "normal");
    }

    /* mdata1 list
     * -- malloc count : 1 (mdata1_p)
     */ /* XXX */
	if (t_p->mdata1_n > 0) {
	    NJV_MCHECK2(mdata1_p,
		NJS_MDATA1 *, sizeof(NJS_MDATA1)*t_p->object_tree_n, "mdata1");
	    for (i=0; i<t_p->object_tree_n; i++) {
	        t_p->mdata1_list[i].data_p = &mdata1_p[i];
	        t_p->mdata1_list[i].name[0] = (char)NULL;
	    }
	}
    /* mdata2 list
     * -- malloc count : 2 (mdata2_p)
     */ /* XXX */
	if (t_p->mdata2_n > 0) {
	    NJV_MCHECK2(mdata2_p,
	        NJS_MDATA2 *, sizeof(NJS_MDATA2)*t_p->object_tree_n, "mdata2");
	    for (i=0; i<t_p->object_tree_n; i++) {
	        t_p->mdata2_list[i].data_p = &mdata2_p[i];
	        t_p->mdata2_list[i].name[0] = (char)NULL;
	    }
	}
	
    /* mdata3 list
     * -- malloc count : 3 (mdata3_p)
     */ /* XXX */
	if (t_p->mdata3_n > 0) {
		    NJV_MCHECK2(mdata3_p,
	        NJS_MDATA3 *, sizeof(NJS_MDATA3)*t_p->object_tree_n, "mdata3");
	    for (i=0; i<t_p->object_tree_n; i++) {
	        t_p->mdata3_list[i].data_p = &mdata3_p[i];
	        t_p->mdata3_list[i].name[0] = (char)NULL;
	    }
	}
    /* mdata4 list
     * -- malloc count : 4 (mdata4_p)
     */ /* XXX */
	if (t_p->mdata4_n > 0) {
	    NJV_MCHECK2(mdata4_p,
	        NJS_MDATA4 *, sizeof(NJS_MDATA4)*t_p->object_tree_n, "mdata4");
	    for (i=0; i<t_p->object_tree_n; i++) {
	        t_p->mdata4_list[i].data_p = &mdata4_p[i];
	        t_p->mdata4_list[i].name[0] = (char)NULL;
	    }
	}

    /* motion list
     * -- malloc count : motion_n
     */
    for (i=0; i<t_p->motion_n; i++) {
        NJV_MCHECK2(t_p->motion_list[i].data_p,
          NJS_MOTION *, sizeof(NJS_MOTION), "motion");
    }

    /*----------------*
     * phase 3 : read *
     *----------------*/
    /* rewind */
    rewind(fp);
    t_p->current_line=0;

    /* reset counter */
    t_p->position_n    = 0;
    t_p->rotation_n    = 0;
    t_p->scale_n       = 0;
    t_p->axevct_n      = 0;
    t_p->xrotation_n   = 0;
    t_p->pointer_n     = 0;	/* shape */
    t_p->point_n       = 0;
    t_p->normal_n      = 0;
    t_p->mdata1_n      = 0;
    t_p->mdata2_n      = 0;
    t_p->mdata3_n      = 0;
    t_p->mdata4_n      = 0;
    t_p->motion_n      = 0;
    t_p->object_n      = 0;
    t_p->action_n      = 0;
     
    do {
        fgets(t_p->buf, NJV_BUFFER_MAX, fp);
        NJV_GetWords(pwl, t_p->buf);
        t_p->current_line++;

        for (i=0; i<cmdn; i++) {
            if (!strcmp(pwl->pwords[0], cmdtab[i].cmdstrings)) {
                if (FALSE != cmdtab[i].func(fp, t_p)) {
                    continue;
                } else {
                    fclose(fp);
                    return FALSE;
                }
            }
        }
    } while (!feof(fp));
    fclose(fp);

    /*--------------------------------------------*
     * phase 4 : chain pointers from name strings *
     *--------------------------------------------*/
#if 0
    /* chain object to actions */
    for (i=t_p->action_n-1; i>=0; i--) {
#ifdef CHAIN_DEBUG1
        fprintf(stderr, "action %s\n", t_p->action_list[i].name);
#endif /* CHAIN_DEBUG1 */
        /* get object */
        if (!strcmp(t_p->action_list[i].objectname, STR_NULL)) {
            t_p->action_list[i].data_p->object = (NJS_OBJECT *)NULL;
            tmpname_p = (char *)NULL;
        } else {
            tmpname_p = t_p->action_list[i].objectname;
            for (j=t_p->object_n-1; j>=0; j--) {
                if (!strcmp(t_p->object_list[j].name, tmpname_p)) {
                    tmpname_p = (char *)NULL; 
                    t_p->action_list[i].data_p->object = 
                        t_p->object_list[j].data_p;
#ifdef CHAIN_DEBUG1
                    fprintf(stderr, "    object %s\n",
                        t_p->object_list[j].name);
#endif /* CHAIN_DEBUG1 */
                    break;
                }
            }
            if (NULL != tmpname_p) {
                fprintf(stderr ,"Warning : Can't chain object %s\n",
                    tmpname_p);
            }
        }
    }
    /* chain motion to actions */
    for (i=t_p->action_n-1; i>=0; i--) {
#ifdef CHAIN_DEBUG2
        fprintf(stderr, "action %s\n", t_p->action_list[i].name);
#endif /* CHAIN_DEBUG2 */
        /* get motion */
        if (!strcmp(t_p->action_list[i].motionname, STR_NULL)) {
            t_p->action_list[i].data_p->motion = (NJS_MOTION *)NULL;
            tmpname_p = (char *)NULL;
        } else {
            tmpname_p = t_p->action_list[i].motionname;
            for (j=t_p->motion_n-1; j>=0; j--) {
                if (!strcmp(t_p->motion_list[j].name, tmpname_p)) {
                    tmpname_p = (char *)NULL; 
                    t_p->action_list[i].data_p->motion = 
                        t_p->motion_list[j].data_p;
#ifdef CHAIN_DEBUG2
                    fprintf(stderr, "    motion %s\n",
                        t_p->action_list[j].name);
#endif /* CHAIN_DEBUG2 */
                    break;
                }
            }
            if (NULL != tmpname_p) {
                fprintf(stderr ,"Warning : Can't chain motion %s\n",
                    tmpname_p);
            }
        }
    }

#endif
	/* chain mdata1 to motions */
	if( t_p->mdata1_n > 0 ){
		for (i=t_p->motion_n-1; i>=0; i--) {
	#ifdef CHAIN_DEBUG3
			fprintf(stderr, "motion %s\n", t_p->motion_list[i].name);
	#endif /* CHAIN_DEBUG3 */
			/* get mdata1 */
			if (!strcmp(t_p->motion_list[i].mdataname, STR_NULL)) {
				t_p->motion_list[i].data_p->mdata = (void *)NULL;
				tmpname_p = (char *)NULL;
			} else {
				tmpname_p = t_p->motion_list[i].mdataname;
				for (j=t_p->object_tree_n-1; j>=0; j--) {
					if (!strcmp(t_p->mdata1_list[j].name, tmpname_p)) {
						tmpname_p = (char *)NULL; 
						t_p->motion_list[i].data_p->mdata = 
							t_p->mdata1_list[j].data_p;
	#ifdef CHAIN_DEBUG3
						fprintf(stderr, "    mdata1 %s\n",
							t_p->mdata1_list[j].name);
	#endif /* CHAIN_DEBUG3 */
						break;
					}
				}
				if (NULL != tmpname_p) {
					fprintf(stderr ,"Warning : Can't chain mdata1 %s\n",
						tmpname_p);
				}
			}
		}
	}
	/* chain mdata2 to motions */
	if( t_p->mdata2_n > 0 ){
		for (i=t_p->motion_n-1; i>=0; i--) {
	#ifdef CHAIN_DEBUG4
z			fprintf(stderr, "motion %s\n", t_p->motion_list[i].name);
	#endif /* CHAIN_DEBUG4 */
			/* get mdata2 */
			if (!strcmp(t_p->motion_list[i].mdataname, STR_NULL)) {
				t_p->motion_list[i].data_p->mdata = (void *)NULL;
				tmpname_p = (char *)NULL;
			} else {
				tmpname_p = t_p->motion_list[i].mdataname;
				for (j=t_p->object_tree_n-1; j>=0; j--) {
					if (!strcmp(t_p->mdata2_list[j].name, tmpname_p)) {
						tmpname_p = (char *)NULL; 
						t_p->motion_list[i].data_p->mdata = 
							t_p->mdata2_list[j].data_p;
	#ifdef CHAIN_DEBUG4
						fprintf(stderr, "    mdata2 %s\n",
							t_p->mdata2_list[j].name);
	#endif /* CHAIN_DEBUG4 */
						break;
					}
				}
				if (NULL != tmpname_p) {
					fprintf(stderr ,"Warning : Can't chain mdata2 %s\n",
						tmpname_p);
				}
			}
		}
	}
	/* chain mdata3 to motions */
	if( t_p->mdata3_n > 0 ){
		for (i=t_p->motion_n-1; i>=0; i--) {
	#ifdef CHAIN_DEBUG5
			fprintf(stderr, "motion %s\n", t_p->motion_list[i].name);
	#endif /* CHAIN_DEBUG5 */
			/* get mdata3 */
			if (!strcmp(t_p->motion_list[i].mdataname, STR_NULL)) {
				t_p->motion_list[i].data_p->mdata = (void *)NULL;
				tmpname_p = (char *)NULL;
			} else {
				tmpname_p = t_p->motion_list[i].mdataname;
				for (j=t_p->object_tree_n-1; j>=0; j--) {
					if (!strcmp(t_p->mdata3_list[j].name, tmpname_p)) {
						tmpname_p = (char *)NULL; 
						t_p->motion_list[i].data_p->mdata = 
							t_p->mdata3_list[j].data_p;
	#ifdef CHAIN_DEBUG5
						fprintf(stderr, "    mdata3 %s\n",
							t_p->motion_list[j].name);
	#endif /* CHAIN_DEBUG5 */
						break;
					}
				}
				if (NULL != tmpname_p) {
					fprintf(stderr ,"Warning : Can't chain mdata3 %s\n",
						tmpname_p);
				}
			}
		}
	}
	/* chain mdata4 to motions */
	if( t_p->mdata4_n > 0 ){
		for (i=t_p->motion_n-1; i>=0; i--) {
	#ifdef CHAIN_DEBUG6
			fprintf(stderr, "motion %s\n", t_p->motion_list[i].name);
	#endif /* CHAIN_DEBUG6 */
			/* get mdata4 */
			if (!strcmp(t_p->motion_list[i].mdataname, STR_NULL)) {
				t_p->motion_list[i].data_p->mdata = (void *)NULL;
				tmpname_p = (char *)NULL;
			} else {
				tmpname_p = t_p->motion_list[i].mdataname;
				for (j=t_p->object_tree_n-1; j>=0; j--) {
					if (!strcmp(t_p->mdata4_list[j].name, tmpname_p)) {
						tmpname_p = (char *)NULL; 
						t_p->motion_list[i].data_p->mdata = 
							t_p->mdata4_list[j].data_p;
	#ifdef CHAIN_DEBUG6
						fprintf(stderr, "    mdata4 %s\n",
							t_p->mdata4_list[j].name);
	#endif /* CHAIN_DEBUG6 */
						break;
					}
				}
				if (NULL != tmpname_p) {
					fprintf(stderr ,"Warning : Can't chain mdata4 %s\n",
						tmpname_p);
				}
			}
		}
	}
	if( t_p->mdata1_n > 0 ){
	    /* chain position to mdata1 */
	    for (i=t_p->object_tree_n-1; i>=0; i--) {
#ifdef CHAIN_DEBUG7
	        fprintf(stderr, "mdata1 %s\n", t_p->mdata1_list[i].name);
#endif /* CHAIN_DEBUG7 */
	        /* get position */
	        if (!strcmp(t_p->mdata1_list[i].pname[0], STR_NULL)) {
	            t_p->mdata1_list[i].data_p->p[0] = (void *)NULL;
	            tmpname_p = (char *)NULL;
	        } else {
	            tmpname_p = t_p->mdata1_list[i].pname[0];
	            for (j=t_p->position_n-1; j>=0; j--) {
	                if (!strcmp(t_p->position_list[j].name, tmpname_p)) {
	                    tmpname_p = (char *)NULL; 
	                    t_p->mdata1_list[i].data_p->p[0] = 
	                        t_p->position_list[j].data_p;
#ifdef CHAIN_DEBUG7
	                    fprintf(stderr, "    position %s\n",
	                        t_p->position_list[j].name);
#endif /* CHAIN_DEBUG7 */
	                    break;
	                }
	            }
	            if (NULL != tmpname_p) {
	                fprintf(stderr ,"Warning : Can't chain position %s\n",
	                    tmpname_p);
	            }
	        }
		}
	}
	if( t_p->mdata2_n > 0 ){
		if( mode == NJV_MODE_NAM ){		
			/* chain position to mdata2 */
			for (i=t_p->object_tree_n-1; i>=0; i--) {
#ifdef CHAIN_DEBUG8
				fprintf(stderr, "mdata2 %s\n", t_p->mdata2_list[i].name);
#endif /* CHAIN_DEBUG8 */
				/* get position */
				if (!strcmp(t_p->mdata2_list[i].pname[0], STR_NULL)) {
					t_p->mdata2_list[i].data_p->p[0] = (void *)NULL;
					tmpname_p = (char *)NULL;
				} else {
					tmpname_p = t_p->mdata2_list[i].pname[0];
					for (j=t_p->position_n-1; j>=0; j--) {
						if (!strcmp(t_p->position_list[j].name, tmpname_p)) {
							tmpname_p = (char *)NULL; 
							t_p->mdata2_list[i].data_p->p[0] = 
								t_p->position_list[j].data_p;
#ifdef CHAIN_DEBUG8
							fprintf(stderr, "    position %s\n",
								t_p->position_list[j].name);
#endif /* CHAIN_DEBUG8 */
							break;
						}
					}
					if (NULL != tmpname_p) {
						fprintf(stderr ,"Warning : Can't chain position %s\n",
							tmpname_p);
					}
				}
				/* get rotation */
				if (!strcmp(t_p->mdata2_list[i].pname[1], STR_NULL)) {
					t_p->mdata2_list[i].data_p->p[1] = (void *)NULL;
					tmpname_p = (char *)NULL;
				} else {
					tmpname_p = t_p->mdata2_list[i].pname[1];
					for (j=t_p->rotation_n-1; j>=0; j--) {
						if (!strcmp(t_p->rotation_list[j].name, tmpname_p)) {
							tmpname_p = (char *)NULL; 
							t_p->mdata2_list[i].data_p->p[1] = 
								t_p->rotation_list[j].data_p;
#ifdef CHAIN_DEBUG8
							fprintf(stderr, "    rotation %s\n",
								t_p->rotation_list[j].name);
#endif /* CHAIN_DEBUG8 */
							break;
						}
					}
					if (NULL != tmpname_p) {
						fprintf(stderr ,"Warning : Can't chain rotation %s\n",
							tmpname_p);
					}
				}
			}
		}
		else{
			/* chain position to mdata2 */
			for (i=t_p->object_tree_n-1; i>=0; i--) {
#ifdef CHAIN_DEBUG8
				fprintf(stderr, "mdata2 %s\n", t_p->mdata2_list[i].name);
#endif /* CHAIN_DEBUG8 */
				/* get pointer */
				if (!strcmp(t_p->mdata2_list[i].pname[0], STR_NULL)) {
					t_p->mdata2_list[i].data_p->p[0] = (void *)NULL;
					tmpname_p = (char *)NULL;
				} else {
					tmpname_p = t_p->mdata2_list[i].pname[0];
					for (j=t_p->pointer_total_n-1; j>=0; j--) {
						if (!strcmp(t_p->pointer_list[j].name, tmpname_p)) {
							tmpname_p = (char *)NULL; 
							t_p->mdata2_list[i].data_p->p[0] = 
								t_p->pointer_list[j].data_p;
#ifdef CHAIN_DEBUG8
							fprintf(stderr, "    pointer %s\n",
								t_p->pointer_list[j].name);
#endif /* CHAIN_DEBUG8 */
							break;
						}
					}
					if (NULL != tmpname_p) {
						fprintf(stderr ,"Warning : Can't chain pointer %s\n",
							tmpname_p);
					}
				}
				/* get pointer */
				if (!strcmp(t_p->mdata2_list[i].pname[1], STR_NULL)) {
					t_p->mdata2_list[i].data_p->p[1] = (void *)NULL;
					tmpname_p = (char *)NULL;
				} else {
					tmpname_p = t_p->mdata2_list[i].pname[1];
					for (j=t_p->pointer_total_n-1; j>=0; j--) {
						if (!strcmp(t_p->pointer_list[j].name, tmpname_p)) {
							tmpname_p = (char *)NULL; 
							t_p->mdata2_list[i].data_p->p[1] = 
								t_p->pointer_list[j].data_p;
#ifdef CHAIN_DEBUG8
							fprintf(stderr, "    pointer %s\n",
								t_p->pointer_list[j].name);
#endif /* CHAIN_DEBUG8 */
							break;
						}
					}
					if (NULL != tmpname_p) {
						fprintf(stderr ,"Warning : Can't chain pointer %s\n",
							tmpname_p);
					}
				}
			}
		}
	}

	if( t_p->mdata3_n > 0 ){
	    /* chain position to mdata3 */
	    for (i=t_p->object_tree_n-1; i>=0; i--) {
#ifdef CHAIN_DEBUG9
	        fprintf(stderr, "mdata3 %s\n", t_p->mdata3_list[i].name);
#endif /* CHAIN_DEBUG9 */
	        /* get position */
	        if (!strcmp(t_p->mdata3_list[i].pname[0], STR_NULL)) {
	            t_p->mdata3_list[i].data_p->p[0] = (void *)NULL;
	            tmpname_p = (char *)NULL;
	        } else {
	            tmpname_p = t_p->mdata3_list[i].pname[0];
	            for (j=t_p->position_n-1; j>=0; j--) {
	                if (!strcmp(t_p->position_list[j].name, tmpname_p)) {
	                    tmpname_p = (char *)NULL; 
	                    t_p->mdata3_list[i].data_p->p[0] = 
	                        t_p->position_list[j].data_p;
#ifdef CHAIN_DEBUG9
	                    fprintf(stderr, "    position %s\n",
	                        t_p->position_list[j].name);
#endif /* CHAIN_DEBUG9 */
	                    break;
	                }
	            }
	            if (NULL != tmpname_p) {
	                fprintf(stderr ,"Warning : Can't chain position %s\n",
	                    tmpname_p);
	            }
	        }
	        /* get rotation */
	        if (!strcmp(t_p->mdata3_list[i].pname[1], STR_NULL)) {
	            t_p->mdata3_list[i].data_p->p[1] = (void *)NULL;
	            tmpname_p = (char *)NULL;
	        } else {
	            tmpname_p = t_p->mdata3_list[i].pname[1];
	            for (j=t_p->rotation_n-1; j>=0; j--) {
	                if (!strcmp(t_p->rotation_list[j].name, tmpname_p)) {
	                    tmpname_p = (char *)NULL; 
	                    t_p->mdata3_list[i].data_p->p[1] = 
	                        t_p->rotation_list[j].data_p;
#ifdef CHAIN_DEBUG9
	                    fprintf(stderr, "    rotation %s\n",
	                        t_p->rotation_list[j].name);
#endif /* CHAIN_DEBUG9 */
	                    break;
	                }
	            }
	            if (NULL != tmpname_p) {
	                fprintf(stderr ,"Warning : Can't chain rotation %s\n",
	                    tmpname_p);
	            }
	        }
	        /* get scale */
	        if (!strcmp(t_p->mdata3_list[i].pname[2], STR_NULL)) {
	            t_p->mdata3_list[i].data_p->p[2] = (void *)NULL;
	            tmpname_p = (char *)NULL;
	        } else {
	            tmpname_p = t_p->mdata3_list[i].pname[2];
	            for (j=t_p->scale_n-1; j>=0; j--) {
	                if (!strcmp(t_p->scale_list[j].name, tmpname_p)) {
	                    tmpname_p = (char *)NULL; 
	                    t_p->mdata3_list[i].data_p->p[2] = 
	                        t_p->scale_list[j].data_p;
#ifdef CHAIN_DEBUG9
	                    fprintf(stderr, "    scale %s\n",
	                        t_p->scale_list[j].name);
#endif /* CHAIN_DEBUG9 */
	                    break;
	                }
	            }
	            if (NULL != tmpname_p) {
	                fprintf(stderr ,"Warning : Can't chain scale %s\n",
	                    tmpname_p);
	            }
	        }
		}
	}
    /* chain point or normal to pointer */
    for (i=t_p->pointer_total_n-1; i>=0; i--) {
#ifdef CHAIN_DEBUG10
        fprintf(stderr, "pointer %s\n", t_p->pointer_list[i].name);
#endif /* CHAIN_DEBUG10 */
        /* get mdata4 */
        if (!strcmp(t_p->pointer_list[i].keyname, STR_NULL)) {
            t_p->pointer_list[i].data_p->key = (void *)NULL;
            tmpname_p = (char *)NULL;
        } else {
            tmpname_p = t_p->pointer_list[i].keyname;
            for (j=t_p->point_n-1; j>=0; j--) {
                if (!strcmp(t_p->point_list[j].name, tmpname_p)) {
                    tmpname_p = (char *)NULL; 
                    t_p->pointer_list[i].data_p->key = 
                        t_p->point_list[j].data_p;
#ifdef CHAIN_DEBUG10
                    fprintf(stderr, "    point %s\n",
                        t_p->point_list[j].name);
#endif /* CHAIN_DEBUG10 */
                    break;
                }
            }
			if(NULL != tmpname_p){
				for (j=t_p->normal_n-1; j>=0; j--) {
					if (!strcmp(t_p->normal_list[j].name, tmpname_p)) {
						tmpname_p = (char *)NULL; 
						t_p->pointer_list[i].data_p->key = 
							t_p->normal_list[j].data_p;
#ifdef CHAIN_DEBUG10
						fprintf(stderr, "    normal %s\n",
							t_p->normal_list[j].name);
#endif /* CHAIN_DEBUG10 */
						break;
					}
				}
			}
            if (NULL != tmpname_p) {
                fprintf(stderr ,"Warning : Can't chain point or normal %s\n",
                    tmpname_p);
            }
        }
    }

    /*-------------------------------------*
     * return object and motion list data  *
     *-------------------------------------*/
    if (0 < t_p->motion_n) {
		if( mode == NJV_MODE_NAM ){
	        nja_p->action.motion  = t_p->motion_list[t_p->motion_n-1].data_p;
			nja_p->motion_tree_n = t_p->object_tree_n;
		}
		else{
			nja_p->shape_p = t_p->motion_list[t_p->motion_n-1].data_p;
			nja_p->shape_tree_n = t_p->object_tree_n;
		}
	}

#if 0
  for (i=t_p->motion_n-1; i>=0; i--) {
        fprintf(stderr, "%s\n", t_p->motion_list[i].name);
        ssn_PrintMotion(t_p->motion_list[i].data_p);
    }
#endif

    /*--------------*
     * free workbuf *
     *--------------*/
    NJV_FreeAll(t_p);

    return TRUE;
}

/*****************************************************************************
 *
 *      Free
 *
 *****************************************************************************/

/*
 * NJV_MotionFree
 */
void NJV_MotionFree(NJS_MOTION *motion_p, Uint16 nbObject)
{
    int i;
	NJS_MDATA1 *mdata1_p;
	NJS_MDATA2 *mdata2_p;
	NJS_MDATA3 *mdata3_p;
	NJS_MDATA4 *mdata4_p;

    if (NULL != motion_p) {
        if (NULL != motion_p->mdata) {
			switch( motion_p->inp_fn ){
			case 1:
                for (i=0; i<nbObject; i++) {
					mdata1_p = ((NJS_MDATA1 *)motion_p->mdata + i);
					if( NULL != mdata1_p->p[0] ){
						NJV_FREE(mdata1_p->p[0]);
					}
				}
				break;

			case 2:
                for (i=0; i<nbObject; i++) {
					mdata2_p = ((NJS_MDATA2 *)motion_p->mdata + i);
					if( NULL != mdata2_p->p[0] ){
						NJV_FREE(mdata2_p->p[0]);
		            }
					if( NULL != mdata2_p->p[1] ){
						NJV_FREE(mdata2_p->p[1]);
		            }
				}
				break;

			case 3:
                for (i=0; i<nbObject; i++) {
					mdata3_p = ((NJS_MDATA3 *)motion_p->mdata + i);
					if( NULL != mdata3_p->p[0] ){
						NJV_FREE(mdata3_p->p[0]);
					}
					if( NULL != mdata3_p->p[1] ){
						NJV_FREE(mdata3_p->p[1]);
		            }
					if( NULL != mdata3_p->p[2] ){
						NJV_FREE(mdata3_p->p[2]);
		            }
				}
				break;

			case 4:
                for (i=0; i<nbObject; i++) {
					mdata4_p = ((NJS_MDATA4 *)motion_p->mdata + i);
					if( NULL != mdata4_p->p[0] ){
						NJV_FREE(mdata4_p->p[0]);
		            }
					if( NULL != mdata4_p->p[1] ){
						NJV_FREE(mdata4_p->p[1]);
		            }
					if( NULL != mdata4_p->p[2] ){
						NJV_FREE(mdata4_p->p[2]);
		            }
					if( NULL != mdata4_p->p[3] ){
						NJV_FREE(mdata4_p->p[3]);
		            }
				}
				break;
			}
        	NJV_FREE(motion_p->mdata);
		}
       	NJV_FREE(motion_p);
	}
}

/*
 * NJV_ShapeFree
 */
void NJV_ShapeFree(NJS_MOTION *shape_p, Uint16 nbObject)
{
    int i;
	NJS_MDATA2 *mdata2_p;
	NJS_MKEY_P *mkey_p_p;

    if (NULL != shape_p) {
        if (NULL != shape_p->mdata) {
			switch( shape_p->inp_fn ){

			case 2:
                for (i=0; i<nbObject; i++) {
					mdata2_p = ((NJS_MDATA2 *)shape_p->mdata + i);
					if( NULL != mdata2_p->p[0] ){
						mkey_p_p = (NJS_MKEY_P *)mdata2_p->p[0];
						if( NULL != mkey_p_p->key )
							NJV_FREE(mkey_p_p->key);
						NJV_FREE(mdata2_p->p[0]);
		            }
					if( NULL != mdata2_p->p[1] ){
						mkey_p_p = (NJS_MKEY_P *)mdata2_p->p[1];
						if( NULL != mkey_p_p->key )
							NJV_FREE(mkey_p_p->key);
						NJV_FREE(mdata2_p->p[1]);
		            }
				}
				break;

			}
        	NJV_FREE(shape_p->mdata);
		}
       	NJV_FREE(shape_p);
	}
}

/*
 * End of File
 */
