/* This includes generic and matfx skin pipes. generic body is in skingcn.c
   as that is shared */
/*===========================================================================*
 *--- Include files ---------------------------------------------------------*
 *===========================================================================*/
#include "dolphin/os.h"

#include <rwcore.h>
#include <rpworld.h>

#include "rpplugin.h"
#include "rpdbgerr.h"

#include "rpskin.h"

#include "skin.h"
#include "skingcn.h"

/*===========================================================================*
 *--- Private Types ---------------------------------------------------------*
 *===========================================================================*/

/*===========================================================================*
 *--- Private Global Variables ----------------------------------------------*
 *===========================================================================*/

static RxPipeline *SkinPipelineGen = (RxPipeline *)NULL;
/* Probably need these for the matfx pipe...
static RxPipeline *SkinPipelineMFX = (RxPipeline *)NULL;
static RxGameCubeAllInOneCallBack OldRenderMFX=(RxGameCubeAllInOneCallBack)NULL;
*/

/*===========================================================================*
 *--- Private Defines -------------------------------------------------------*
 *===========================================================================*/

/*===========================================================================*
 *--- Local Types -----------------------------------------------------------*
 *===========================================================================*/

/*===========================================================================*
 *--- Local Global Variables ------------------------------------------------*
 *===========================================================================*/
static const char rcsid[] __RWUNUSED__ = "@@(#)$Id:";

/*===========================================================================*
 *--- Private functions -----------------------------------------------------*
 *===========================================================================*/

/****************************************************************************
 _rpSkinPipelinesCreate

 Create the skinning pipelines.

 Inputs : None
 Outputs: RwBool - on success.
 */
RwBool
_rpSkinPipelinesCreate(RwUInt32 type)
{
    RxPipeline *pipe;
    RxLockedPipe *lpipe;
    RxNodeDefinition *nodeDfn;
    RxPipelineNode *node;

    RWFUNCTION(RWSTRING("_rpSkinPipelinesCreate"));

    pipe = RxPipelineCreate();
    RWASSERT(NULL != pipe);

    lpipe = RxPipelineLock(pipe);
    RWASSERT(NULL != lpipe);

    nodeDfn = RxNodeDefinitionGetGameCubeAtomicAllInOne();
    RWASSERT(NULL != nodeDfn);

    lpipe = RxLockedPipeAddFragment(lpipe, NULL, nodeDfn, NULL);
    RWASSERT(NULL != lpipe);

    lpipe = RxLockedPipeUnlock(lpipe);
    RWASSERT(NULL != lpipe);
    RWASSERT(pipe == (RxPipeline *)lpipe);

    node = RxPipelineFindNodeByName(pipe, nodeDfn->name, NULL, NULL);
    RWASSERT(NULL != node);

    _rpSkinOldRenderGP = RxGameCubeAllInOneGetRenderCallBack(node);
    RWASSERT(NULL != _rpSkinOldRenderGP);

    _rxGameCubeAllInOneSetNoInstanceFlags(node,
                                     rxGEOMETRY_POSITIONS | rxGEOMETRY_NORMALS);

    RxGameCubeAllInOneSetRenderCallBack(node, _rpSkinMatBlendAtomicRender);

    SkinPipelineGen = pipe;

    /* Create MatFX pipe here !! */

    RWRETURN(TRUE);
}

/****************************************************************************
 _rpSkinPipelinesDestroy

 Destroy the skinning pipelines.

 Inputs : None
 Outputs: RwBool - on success.
 */
RwBool
_rpSkinPipelinesDestroy(void)
{
    RWFUNCTION(RWSTRING("_rpSkinPipelinesDestroy"));

    if(NULL != SkinPipelineGen)
    {
        RxPipelineDestroy(SkinPipelineGen);
    }

    SkinPipelineGen = (RxPipeline *)NULL;
    _rpSkinOldRenderGP = (RxGameCubeAllInOneCallBack)NULL;

    /* Need to do MatFX pipe here !! */

    RWRETURN(TRUE);
}

/****************************************************************************
 _rpSkinPipelinesAttach

 Attach the gcn skinning pipeline to an atomic.

 Inputs : atomic *   - Pointer to the atomic.
 Outputs: RpAtomic * - Pointer to the atomic on success.
 */
RpAtomic *
_rpSkinPipelinesAttach(RpAtomic *atomic)
{
    RxPipeline *pipeline;

    RWFUNCTION(RWSTRING("_rpSkinPipelinesAttach"));
    RWASSERT(NULL != atomic);

    pipeline = SkinPipelineGen;
    RWASSERT(NULL != pipeline);

    /* Only overload the pipeline - if it's the default one. */
    if(NULL == atomic->pipeline)
    {
        /* Actually need to make the decision about generic/matfx here !! */
        atomic = RpAtomicSetPipeline(atomic, pipeline);
    }

    RWRETURN(atomic);
}

