/*
 *
 * VRML to RW converter plug-in
 */

/****************************************************************************
 *                                                                         
 * VRML 2.0 to RW3.0 Converter
 * Copyright (C) 1998 Criterion Technologies
 *
 * Author  : Damian Scallan 
 *
 * Module  : NameGen.c
 *                                                                         
 * Purpose : Creates unique name Id's
 *
 *                                                                         
 ****************************************************************************/

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

#include "rpplugin.h"
#include <rpdbgerr.h>
#include "rpvrmlanim.h"
#include "rpvrml.h"
#include "namegen.h"

static const char __RWUNUSED__ rcsid[] =
    "@@(#)$Id: namegen.c,v 1.20 2001/02/05 11:44:23 johns Exp $";

/****************************************************************************
 Local Types
 */

typedef struct BaseNameItem BaseNameItem;
struct BaseNameItem
{
    RwChar              baseName[9];
    RwInt32             id;
};

/****************************************************************************
 Local (Static) Prototypes
 */

static BaseNameItem *BaseName_Create(RwChar * baseName);
static RwBool       BaseName_Destroy(BaseNameItem * nameItem);

/****************************************************************************
 Local (static) Globals
 */

LLinkList           nameGenTable; /* of BaseNameItem */

/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    BaseNameItem methods

   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

static BaseNameItem *
BaseName_Create(RwChar * baseName)
{
    RWFUNCTION(RWSTRING("BaseName_Create"));
    RWASSERT(baseName);

    if (baseName)
    {
        BaseNameItem       *newNameItem;

        newNameItem = (BaseNameItem *) RwMalloc(sizeof(BaseNameItem));
        if (!newNameItem)
        {
            RWRETURN((BaseNameItem *)NULL);
        }

        rwstrcpy(newNameItem->baseName, baseName);
        newNameItem->id = 0;

        RWRETURN(newNameItem);
    }

    RWERROR((E_RW_NULLP));
    RWRETURN((BaseNameItem *)NULL);
}

static              RwBool
BaseName_Destroy(BaseNameItem * nameItem)
{
    RWFUNCTION(RWSTRING("BaseName_Destroy"));
    RWASSERT(nameItem);

    if (nameItem)
    {
        RwFree(nameItem);

        RWRETURN(TRUE);
    }

    RWERROR((E_RW_NULLP));
    RWRETURN(FALSE);
}

/* !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

    NameGen methods

   !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! */

void
NameGen_Init(void)
{
    RWFUNCTION(RWSTRING("NameGen_Init"));

    LLinkList_Init(&nameGenTable);

    RWRETURNVOID();
}

void
NameGen_Destroy(void)
{
    RWFUNCTION(RWSTRING("NameGen_Destroy"));

    LLinkList_Destroy(&nameGenTable, (linkCallback) BaseName_Destroy);

    RWRETURNVOID();
}

RwChar             *
NameGen_CreateName(RwChar * baseName)
{
    RWFUNCTION(RWSTRING("NameGen_CreateName"));
    RWASSERT(baseName);

    if (baseName)
    {
        RwBool              inList = FALSE;
        BaseNameItem       *nameItem;
        RwInt32             strLength;
        RwInt32             id = 0;
        RwChar              idString[8];
        RwChar             *nameId;

        LLinkList_IteratorReset(&nameGenTable);
        while ((nameItem =
                (BaseNameItem *) LLinkList_IteratorNext(&nameGenTable)))
        {
            if (rwstrcmp(baseName, nameItem->baseName) == 0)
            {
                id = ++nameItem->id;
                inList = TRUE;
                break;
            }
        }

        if (!inList)
        {
            BaseNameItem       *newNameItem;

            /* since first set id to zero */
            id = 0;

            /* create new item */
            newNameItem = BaseName_Create(baseName);
            if (!newNameItem)
            {
                RWRETURN((char *)NULL);
            }

            /* add to the name list */
            if (!LLinkList_AddData(&nameGenTable, newNameItem))
            {
                RwFree(newNameItem);

                RWRETURN((char *)NULL);
            }
        }

        /* create the new name */
        rwsprintf(idString, "%x", id);
        strLength = rwstrlen(idString) + 1;
        strLength += rwstrlen(baseName) + 1;
        nameId = (RwChar *) RwMalloc(strLength * sizeof(RwChar));
        if (!nameId)
        {
            RWRETURN((char *)NULL);
        }

        rwsprintf(nameId, "%s_%s", baseName, idString);

        RWRETURN(nameId);
    }

    RWERROR((E_RW_NULLP));
    RWRETURN((char *)NULL);
}
