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

/****************************************************************************
 *
 * VRML 2.0 to RW3.0 Converter
 * Copyright (C) 1997 Criterion Technologies
 *
 * Author  : Damian Scallan 
 *
 * Module  : Stack.c
 *                                                                         
 * Purpose : Polymorphic stack + methods
 *
 ****************************************************************************/

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

#include <stdlib.h>

#include "rpplugin.h"
#include "stack.h"
#include "rpvrmlanim.h"
#include "rpvrml.h"
#include "llinklist.h"

static const char __RWUNUSED__ rcsid[] =
    "@@(#)$Id: stack.c,v 1.19 2001/01/26 12:10:58 johns Exp $";

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

   Stack methods

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

void
Stack_Init(LLStack * Stack)
{
    RWFUNCTION(RWSTRING("Stack_Init"));
    RWASSERT(Stack);
    Stack->Items = 0;
    LLinkList_Init(&Stack->StackList);

    RWRETURNVOID();
}

VRMLBool
Stack_IsEmpty(LLStack * Stack)
{
    RWFUNCTION(RWSTRING("Stack_IsEmpty"));

    if (LLinkList_IsEmpty(&Stack->StackList))
    {
        RWASSERT(Stack->Items == 0);
        RWRETURN(TRUE);
    }
    RWRETURN(FALSE);
}

void               *
Stack_Pop(LLStack * Stack)
{
    RWFUNCTION(RWSTRING("Stack_Pop"));
    RWASSERT(Stack);
    if (!LLinkList_IsEmpty(&Stack->StackList))
    {
        LLLink             *Top;
        void               *Data;

        Top = LLinkList_GetFirst(&Stack->StackList);
        Data = LLLink_GetData(Top);

        LLinkList_RemoveLink(&Stack->StackList, Top);
        LLLink_Destroy(Top);
        --Stack->Items;

        RWRETURN(Data);
    }
    RWRETURN(NULL);
}

void               *
Stack_Top(LLStack * Stack)
{
    RWFUNCTION(RWSTRING("Stack_Top"));
    RWASSERT(Stack);
    if (!LLinkList_IsEmpty(&Stack->StackList))
    {
        LLLink             *Top;
        void               *Data;

        Top = LLinkList_GetFirst(&Stack->StackList);
        Data = LLLink_GetData(Top);

        RWRETURN(Data);
    }
    RWRETURN(NULL);
}

VRMLBool
Stack_Push(LLStack * Stack, void *Data)
{
    LLLink             *Link;

    RWFUNCTION(RWSTRING("Stack_Push"));
    RWASSERT(Data);
    Link = LLLink_Create(Data);
    if (Link)
    {
        LLinkList_AddLink(&Stack->StackList, Link);
        ++Stack->Items;
        RWRETURN(TRUE);
    }
    RWRETURN(FALSE);
}
