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

/*****************************************************************************
 *
 *      global
 *
 *****************************************************************************/

NJV_WordsList wl, *pwl;

/*****************************************************************************
 *
 *      GetWords for nja and x file
 *
 *****************************************************************************/
/*
 * NJV_GetWordsInit
 */
void NJV_GetWordsInit(NJV_WordsList *pwl)
{
    register char *ck = pwl->ck;
    int i;

    /* init char check table */
    for (i = 0; i < 256; i++) {
        ck[i] = NJV_CK_SPACE;
        if ( (i >= 'a' && i <= 'z')
          || (i >= 'A' && i <= 'Z')
          || (i >= '0' && i <= '9')
          || (i == '-' || i == '.' || i == '/' || i == '_' || i == '$' || i == ':' || i == '\\') ){
            ck[i] = NJV_CK_STRING;
        } else if (i == '{') {
            ck[i] = NJV_CK_BRACE_IN;
        } else if (i == '}') {
            ck[i] = NJV_CK_BRACE_OUT;
        } else if (i == '\0') {
            ck[i] = NJV_CK_LINEEND;
        }
    }
    pwl->bracePushPop=0;
}

/*
 * NJV_GetWords (nja and x file version)
 */
void NJV_GetWords(NJV_WordsList *pwl, char *buf)
{
    register char            ck;
    register char      *p = buf;
    int              wordflag=0;

    pwl->word_n = 0;
    do {
        switch(ck = pwl->ck[*p]) {
            case NJV_CK_BRACE_IN:
            case NJV_CK_BRACE_OUT:
                if (ck == NJV_CK_BRACE_IN) {
                    pwl->bracePushPop++;
                } else {
                    pwl->bracePushPop--;
                }
            case NJV_CK_STRING:
                if (!wordflag) {
                    wordflag = 1;
                    pwl->pwords[pwl->word_n++] = p;
                }
                break;
            case NJV_CK_SPACE:
            case NJV_CK_LINEEND:
                if (wordflag) {
                    wordflag = 0;
                    *p = '\0';
                }
                break;
        }
        p++;
    } while (ck != NJV_CK_LINEEND);

#ifdef NJV_DEBUG_GETWORD
    {   int i;
        for (i = 0; i < pwl->word_n; i++)
            fprintf(stderr, "%d %s\n", i, pwl->pwords[i]);
    }
#endif /* _DEBUG */
}

/*****************************************************************************
 *
 *      Malloc table
 *
 *****************************************************************************/
/*
 * error
 */
void NJV_Error(char *format, char *message)
{
    fprintf(stderr, format, message);
    exit(0);
}

/*
 * init malloc table
 */
void NJV_MallocInit(NJV_WorkTab *worktab_p)
{
    NJV_MallocTable *tab_p = &worktab_p->mtable;
    NJV_MallocPage                      *page_p;

    tab_p->pagesize = NJV_PAGE_SIZE;

    if (NULL == (page_p = (NJV_MallocPage *)malloc(sizeof(NJV_MallocPage)))) {
        NJV_Error("Error: Can't malloc %s\n", "page");
    }
    if (NULL == (page_p->buf = (char *)malloc(tab_p->pagesize))) {
        NJV_Error("Error: Can't malloc buf %s\n", "buf");
    }

    tab_p->pagetop = (NJV_MallocPage *)page_p;
    tab_p->page    = (NJV_MallocPage *)page_p;
    tab_p->prev_p  = (NJV_MallocPage *)NULL;
    tab_p->current = 0L;
    tab_p->pagenum = 1;
}

/*
 * malloc table
 */
void *NJV_Malloc(NJV_WorkTab *worktab_p, int bytesize, char *message)
{
    NJV_MallocTable *tab_p = &worktab_p->mtable;
    NJV_MallocPage                      *page_p;
    void                                 *tmp_p;
    int                                       j;

    /* get long boundary bytesize */
    if (0 < (j = bytesize % 4)) {
        bytesize += 4 - j;
    }

    /* big alloc */
    if (bytesize > tab_p->pagesize) {
        if (NULL == (page_p =
                    (NJV_MallocPage *)malloc(sizeof(NJV_MallocPage)))) {
            NJV_Error("Error: Can't malloc big page %s\n", message);
        }
        if (NULL == (page_p->buf = (char *)malloc(bytesize))) {
            NJV_Error("Error: Can't malloc buf %s\n", message);
        }
        page_p->next_p = tab_p->pagetop;                 /* set current    */
        tab_p->pagetop = page_p;                         /* insert myself  */
        if (NULL == tab_p->prev_p) {
            tab_p->prev_p  = page_p;                     /* set prev       */
        }
        tab_p->pagenum++;
        tmp_p = page_p->buf;
    } else {
        /* check page */
        if (tab_p->current + bytesize > tab_p->pagesize) {
            if (NULL == (page_p =
                        (NJV_MallocPage *)malloc(sizeof(NJV_MallocPage)))) {
                NJV_Error("Error: Can't malloc page %s\n", message);
            }
            if (NULL == (page_p->buf =
                        (char *)malloc(tab_p->pagesize))) {
                NJV_Error("Error: Can't malloc buf %s\n", message);
            }
            tab_p->page->next_p = page_p;                /* set new chain  */
            tab_p->prev_p = tab_p->page;                 /* set prev       */
            tab_p->page = page_p;                        /* set new page   */
            tab_p->page->next_p = (NJV_MallocPage *)NULL; /* set chain end  */
            tab_p->pagenum++;
            tab_p->current = 0L;                         /* reset counter  */
        }
        tmp_p = &tab_p->page->buf[tab_p->current];
        tab_p->current += bytesize;
    }

    return (void *)tmp_p;
}

/*
 * copy string
 */
char *NJV_Strdup(NJV_WorkTab *worktab_p, char *filename)
{
   char                *tmp_p;
   int len = strlen(filename);

    if (NULL == filename || 0 == len) {
        return (char *)NULL;
    } else {
        tmp_p = NJV_Malloc(worktab_p, len+1, "strdup");
        strcpy(tmp_p, filename);
        return tmp_p;
    }
}

/*
 * free malloc table
 */
void NJV_FreeAll(NJV_WorkTab *worktab_p)
{
    NJV_MallocTable        *tab_p = &worktab_p->mtable;
    NJV_MallocPage *page_p = worktab_p->mtable.pagetop;
    NJV_MallocPage                              *tmp_p;
    int                                              j;
    
    for (j=0; j<tab_p->pagenum; j++) {
        tmp_p = page_p;
        if (NULL != tmp_p) {
            page_p = page_p->next_p;
            if (NULL != tmp_p->buf) {
                free(tmp_p->buf);
            }
            free(tmp_p);        /* NJV_MallocPage free */
        }
    }

    tab_p->pagetop = (NJV_MallocPage *)NULL;
    tab_p->page = (NJV_MallocPage *)NULL;
    tab_p->prev_p = (NJV_MallocPage *)NULL;
    tab_p->pagenum = 0;
    tab_p->current = 0;
}

int NJV_GetNormalSize(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, "Normal %d\n", n);
#endif
    return n;
}

int NJV_GetPointSize(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, "Point %d\n", n);
#endif
    return n;
}

/*--------------*/
/* 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_ReadPOINT
 */
int ssn_ReadPOINT(FILE *fp, NJV_WorkTab *t_p)
{
    int        done = 0;
    char       *name_p = t_p->point_list[t_p->point_n].name;
    NJS_VECTOR *tmp_p = t_p->point_list[t_p->point_n++].data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadPOINT\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;
                    tmp_p->x = NJV_ATOF(pwl->pwords[1]);
                    tmp_p->y = NJV_ATOF(pwl->pwords[2]);
                    tmp_p->z = NJV_ATOF(pwl->pwords[3]);
                    tmp_p++;
                }
            } while (!done);
        }
    } while (!done);

    return TRUE;
}

/*
 * ssn_ReadNORMAL
 */
int ssn_ReadNORMAL(FILE *fp, NJV_WorkTab *t_p)
{
    int        done = 0;
    char       *name_p = t_p->normal_list[t_p->normal_n].name;
    NJS_VECTOR *tmp_p = t_p->normal_list[t_p->normal_n++].data_p;

#ifdef NJV_DEBUG
    fprintf(stderr, "ssn_ReadNORMAL\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;
                    tmp_p->x = NJV_ATOF(pwl->pwords[1]);
                    tmp_p->y = NJV_ATOF(pwl->pwords[2]);
                    tmp_p->z = NJV_ATOF(pwl->pwords[3]);
                    tmp_p++;
                }
            } while (!done);
        }
    } while (!done);

    return TRUE;
}


/*****************************************************************************
 *
 *      Debug Print
 *
 *****************************************************************************/
/*
 * ssn_PrintTexname
 */
void ssn_PrintTexname(NJS_TEXNAME *texname_p)
{
    fprintf(stderr, "filename %s\n", texname_p->filename);
    fprintf(stderr, "attr %x\n", texname_p->attr);
    fprintf(stderr, "texaddr %x\n", texname_p->texaddr);
}

/*
 * ssn_PrintObject
 */
void ssn_PrintObject(NJS_OBJECT *object_p)
{
    int            i, j;
    int       mat_max=0;
    NJS_MESHSET   *ms_p;
    NJS_MATERIAL *mat_p;

    fprintf(stderr, "<object_p> %x\n", object_p);
    fprintf(stderr, "evalflags %x\n", object_p->evalflags);
    fprintf(stderr, "pos %f %f %f\n",
        object_p->pos[0], object_p->pos[1], object_p->pos[2]);
    fprintf(stderr, "angle %d %d %d\n",
        object_p->ang[0], object_p->ang[1], object_p->ang[2]);
    fprintf(stderr, "scl %f %f %f\n",
        object_p->scl[0], object_p->scl[1], object_p->scl[2]);
    if (object_p->child) {
        fprintf(stderr, "child %x\n", object_p->child);
    } else {
        fprintf(stderr, "child NULL\n");
    }
    if (object_p->sibling) {
        fprintf(stderr, "sibling %x\n", object_p->sibling);
    } else {
        fprintf(stderr, "sibling NULL\n");
    }

    if (NULL != object_p->model) {
        fprintf(stderr, "<model> %x\n", object_p->model);
        fprintf(stderr, "nbPoints %d\n", object_p->model->nbPoint);
        fprintf(stderr, "nbMeshset %d\n", object_p->model->nbMeshset);
        fprintf(stderr, "nbMat %d\n", object_p->model->nbMat);
        fprintf(stderr, "center %f %f %f\n",
            object_p->model->center.x,
            object_p->model->center.y,
            object_p->model->center.z);
        fprintf(stderr, "radius %f\n", object_p->model->r);
        for (i=0; i<object_p->model->nbMeshset; i++) {
            ms_p = &object_p->model->meshsets[i];
            fprintf(stderr, "meshset i %d %x\n", i, ms_p);
            fprintf(stderr, "type_matId %x\n", ms_p->type_matId);
            if (mat_max < (j = ms_p->type_matId & 0x3fff)) {
                mat_max = j;
            }
            fprintf(stderr, "nbMesh %d\n", ms_p->nbMesh);
            fprintf(stderr, "meshes %x\n", ms_p->meshes);
            fprintf(stderr, "attrs %x\n", ms_p->attrs);
            fprintf(stderr, "normals %x\n", ms_p->normals);
            fprintf(stderr, "vertcolor %x\n", ms_p->vertcolor);
            fprintf(stderr, "vertuv %x\n", ms_p->vertuv);
            fprintf(stderr, "--\n");
        }
        for (i=0; i<=mat_max; i++) {
            mat_p = &object_p->model->mats[i];
            fprintf(stderr, "<material> %x\n", mat_p);
            fprintf(stderr, "diffuse %d %d %d %d\n",
                mat_p->diffuse.argb.a, mat_p->diffuse.argb.r,
                mat_p->diffuse.argb.g, mat_p->diffuse.argb.b);
            fprintf(stderr, "specular %d %d %d\n", mat_p->specular.argb.r,
                mat_p->specular.argb.g, mat_p->specular.argb.b);
            fprintf(stderr, "exponent %f\n", mat_p->exponent);
            fprintf(stderr, "attr_texId %x\n", mat_p->attr_texId);
            fprintf(stderr, "attrflags %x\n", mat_p->attrflags);
        }
    }
    fprintf(stderr, "\n");
}

/*
 * ssn_PrintMotion
 */
void ssn_PrintMotion(NJS_MOTION *motion_p)
{
    NJS_MKEY_F   *mkf_p;
	NJS_MDATA1   *m1_p;
	NJS_MDATA2   *m2_p;
	NJS_MDATA3   *m3_p;
	NJS_MDATA4   *m4_p;

    fprintf(stderr, "<motion_p> %x\n", motion_p);
    fprintf(stderr, "nbFrame %d\n", motion_p->nbFrame);
    fprintf(stderr, "type %d\n", motion_p->type);
    fprintf(stderr, "inp_fn %d\n", motion_p->inp_fn);

    if (NULL != motion_p->mdata) {
        fprintf(stderr, "<mdata> %x\n", motion_p->mdata);

		switch(motion_p->inp_fn){
			case 1:
				m1_p = (NJS_MDATA1*)motion_p->mdata;
				fprintf(stderr, "p[0] %x\n", m1_p->p[0]);
				fprintf(stderr, "nb %d \n",  m1_p->nb[0]);
				if(NULL != m1_p->p[0]){
					mkf_p = (NJS_MKEY_F *)m1_p->p[0];
					fprintf(stderr, "keyframe %d \n",mkf_p->keyframe);
					fprintf(stderr, "key[0] %f \n",  mkf_p->key[0]);
					fprintf(stderr, "key[1] %f \n",  mkf_p->key[1]);
					fprintf(stderr, "key[2] %f \n",  mkf_p->key[2]);
				}
			break;

			case 2:
				m2_p = (NJS_MDATA2*)motion_p->mdata;
				fprintf(stderr, "p[0] %x\n", m2_p->p[0]);
				fprintf(stderr, "p[1] %x\n", m2_p->p[1]);
				fprintf(stderr, "nb %d \n",  m2_p->nb[0]);
				fprintf(stderr, "nb %d \n",  m2_p->nb[1]);
				if(NULL != m2_p->p[0]){
					mkf_p = (NJS_MKEY_F *)m2_p->p[0];
					fprintf(stderr, "keyframe %d \n",mkf_p->keyframe);
					fprintf(stderr, "key[0] %f \n",  mkf_p->key[0]);
					fprintf(stderr, "key[1] %f \n",  mkf_p->key[1]);
					fprintf(stderr, "key[2] %f \n",  mkf_p->key[2]);
				}
			break;

			case 3:
				m3_p = (NJS_MDATA3 *)motion_p->mdata;
				fprintf(stderr, "p[0] %x\n",  m3_p->p[0]);
				fprintf(stderr, "p[1] %x\n",  m3_p->p[1]);
				fprintf(stderr, "p[2] %x\n",  m3_p->p[2]);
				fprintf(stderr, "nb %d \n",  m3_p->nb[0]);
				fprintf(stderr, "nb %d \n",  m3_p->nb[1]);
				fprintf(stderr, "nb %d \n",  m3_p->nb[2]);
				if(NULL != m3_p->p[0]){
					mkf_p = (NJS_MKEY_F *)m3_p->p[0];
					fprintf(stderr, "keyframe %d \n",mkf_p->keyframe);
					fprintf(stderr, "key[0] %f \n",  mkf_p->key[0]);
					fprintf(stderr, "key[1] %f \n",  mkf_p->key[1]);
					fprintf(stderr, "key[2] %f \n",  mkf_p->key[2]);
				}
			break;

			case 4:
				m4_p = (NJS_MDATA4*)motion_p->mdata;
				fprintf(stderr, "p[0] %x\n", m4_p->p[0]);
				fprintf(stderr, "p[1] %x\n", m4_p->p[1]);
				fprintf(stderr, "p[2] %x\n", m4_p->p[2]);
				fprintf(stderr, "p[3] %x\n", m4_p->p[3]);
				fprintf(stderr, "nb %d \n",  m4_p->nb[0]);
				fprintf(stderr, "nb %d \n",  m4_p->nb[1]);
				fprintf(stderr, "nb %d \n",  m4_p->nb[2]);
				fprintf(stderr, "nb %d \n",  m4_p->nb[3]);
				if(NULL != m4_p->p[0]){
					mkf_p = (NJS_MKEY_F *)m4_p->p[0];
					fprintf(stderr, "keyframe %d \n",mkf_p->keyframe);
					fprintf(stderr, "key[0] %f \n",  mkf_p->key[0]);
					fprintf(stderr, "key[1] %f \n",  mkf_p->key[1]);
					fprintf(stderr, "key[2] %f \n",  mkf_p->key[2]);
				}
			break;
		}
	}
}

/*
 * End of File
 */
