/*
 *  ======== rotate.c ========
 *  Color rotation API, exposed to the application.
 *
 *  The methods defined here must be independent of whether the underlying
 *  algorithm is executed locally or remotely.
 *
 *  In fact, these methods must exist on *both* the client and server; the
 *  ROTATE skeletons (rotate_skel.c) call these API's to create instances on the
 *  remote CPU.
 */
#include <xdc/std.h>

#include <ti/xdais/ialg.h>
#include <ti/sdo/ce/visa.h>

#include <ti/sdo/ce/trace/gt.h>

#include "rotate.h"
#include "_rotate.h"

/* default params*/
ROTATE_Params ROTATE_PARAMS = {
    {sizeof(ROTATE_Params),      /* size of structure */
    FALSE},                      /* Bool reverseImage */
    0                            /* Max Image Size */ 
};

#define GTNAME "ti.sdo.apps.extensions.rotate.ROTATE"

static GT_Mask curTrace = {NULL,NULL};


/*
 *  ======== ROTATE_create ========
 */
ROTATE_Handle ROTATE_create(Engine_Handle server, String name,
    ROTATE_Params *params)
{
    ROTATE_Handle visa;
    static Bool curInit = FALSE;

    if (curInit != TRUE) {
        curInit = TRUE;
        GT_create(&curTrace, GTNAME);
    }

    GT_3trace(curTrace, GT_ENTER, "ROTATE_create> "
        "Enter (server=0x%x, name='%s', params=0x%x)\n",
        server, name, params);

    if (params == NULL) {
        params = &ROTATE_PARAMS;
    }

    visa = VISA_create(server, name, (IALG_Params *)params,
        sizeof (_ROTATE_Msg), "ti.sdo.apps.extensions.rotate.IROTATE");

    GT_1trace(curTrace, GT_ENTER, "ROTATE_create> return (0x%x)\n", visa);

    return (visa);
}

/*
 *  ======== ROTATE_delete ========
 */
Void ROTATE_delete(ROTATE_Handle handle)
{
    GT_1trace(curTrace, GT_ENTER, "ROTATE_delete> Enter (handle=0x%x)\n",
        handle);

    VISA_delete(handle);

    GT_0trace(curTrace, GT_ENTER, "ROTATE_delete> return\n");
}

/*
 *  ======== ROTATE_process ========
 *  This method must be the same for both local and remote invocation;
 *  each call site in the client might be calling different implementations
 *  (one that marshalls & sends and one that simply calls).
 */
XDAS_Int32 ROTATE_process(ROTATE_Handle handle, char inBuf[], char outBuf[],
    XDAS_Int32 bufSize, XDAS_Int16 cosine, XDAS_Int16 sine)
{
    Int32 retVal = ROTATE_EFAIL;
    ROTATE_InArgs inArgs;

    GT_5trace(curTrace, GT_ENTER, "ROTATE_process> "
        "Enter (handle=0x%x, inBuf=0x%x, outBuf=0x%x, cosine=0x%x, "
        "sine=0x%x)\n", 
        handle, inBuf, outBuf, cosine, sine);

    /* Setting up inArgs for the process call */
    inArgs.bufSize = bufSize;
    inArgs.cosine = cosine;
    inArgs.sine = sine;

    /* Call the process function of the (remote) stub or (local) algorithm */
    if (handle) {
        IROTATE_ADAPT_Fxns *fxns =
            (IROTATE_ADAPT_Fxns *)VISA_getAlgFxns((VISA_Handle)handle);
        IROTATE_Handle alg = VISA_getAlgHandle((VISA_Handle)handle);

        if (fxns && (alg != NULL)) {
            VISA_enter((VISA_Handle)handle);
            retVal = fxns->process(alg, (XDAS_Int8 *)inBuf, 
                (XDAS_Int8 *)outBuf, &inArgs);
            VISA_exit((VISA_Handle)handle);
        }
    }

    GT_2trace(curTrace, GT_ENTER, "ROTATE_process> "
        "Exit (handle=0x%x, retVal=0x%x)\n", handle, retVal);

    return (retVal);
}

