/*
 * SFLIP  A SIMULINK block to flip the input vector.
 * DSP Blockset S-Function to flip input vector.
 * This SIMULINK S-function reverses the order of the input vector 
 *  elements; it is called by the Flip block in the DSP Blockset.
 *
 *  Copyright 1995-2000 The MathWorks, Inc.
 *  $Revision: 1.12 $  $Date: 2000/06/14 14:28:00 $
 */
#define S_FUNCTION_NAME  sflip
#define S_FUNCTION_LEVEL 2

#define DATA_TYPES_IMPLEMENTED

#include "simstruc.h"
#include "dsptypes.h"

enum {NUM_ARGS=0};
enum {INPORT=0}; 
enum {OUTPORT=0}; 


static void mdlInitializeSizes(SimStruct *S)
{
    ssSetNumSFcnParams(S,  NUM_ARGS);
    if (ssGetNumSFcnParams(S) != ssGetSFcnParamsCount(S)) return;

    /* Inputs: */
    if (!ssSetNumInputPorts(S, 1)) return;
    ssSetInputPortWidth(            S, INPORT, DYNAMICALLY_SIZED);
    ssSetInputPortDirectFeedThrough(S, INPORT, 1);
    ssSetInputPortComplexSignal(    S, INPORT, COMPLEX_INHERITED);
    ssSetInputPortReusable(        S, INPORT, 1);
    ssSetInputPortOverWritable(     S, INPORT, 1);

    /* Outputs: */
    if (!ssSetNumOutputPorts(S,1)) return;
    ssSetOutputPortWidth(        S, OUTPORT, DYNAMICALLY_SIZED);
    ssSetOutputPortComplexSignal(S, OUTPORT, COMPLEX_INHERITED);  
    ssSetOutputPortReusable(    S, OUTPORT, 1);

    ssSetNumSampleTimes(S, 1);
    ssSetOptions(S, SS_OPTION_EXCEPTION_FREE_CODE);
}


static void mdlInitializeSampleTimes(SimStruct *S)
{
    ssSetSampleTime(S, 0, INHERITED_SAMPLE_TIME);
    ssSetOffsetTime(S, 0, 0.0);
}


static void mdlOutputs(SimStruct *S, int_T tid)
{
    const boolean_T inplace = (boolean_T)(ssGetInputPortBufferDstPort(S, INPORT) == OUTPORT);
    const boolean_T c0      = (boolean_T)(ssGetInputPortComplexSignal(S,INPORT) == COMPLEX_YES);
    int_T           width   = ssGetInputPortWidth(S,INPORT);

    if (!c0) {
    	/*
         * Real
         */
        if (inplace) {
            /* In-place and contiguous: */

            /* Get first pointer: */
            real_T *top    = ssGetOutputPortRealSignal(S,OUTPORT);
            real_T *bottom = top + width-1;
            int_T   i      = width / 2;  /* if odd, = floor(width/2) */
            while(i-- > 0) {
                real_T tmp = *top;
                *top++     = *bottom;
                *bottom--  = tmp;
            }

        } else {
    	    InputRealPtrsType  uptr = ssGetInputPortRealSignalPtrs(S,INPORT);
    	    real_T            *y    = ssGetOutputPortRealSignal(S,OUTPORT) + (width-1);

            while(width-- > 0) {
                *y-- = **(uptr++);
            }
        }

    } else {
   	/*
         * Complex
         */
        if (inplace) {
            /* In-place and contiguous: */

            /* Get first pointer: */
            creal_T *top    = (creal_T *)ssGetOutputPortSignal(S,OUTPORT);
            creal_T *bottom = top + width-1;
            int_T    i      = width / 2;  /* if odd, = floor(width/2) */
            while(i-- > 0) {
                creal_T tmp = *top;
                *top++      = *bottom;
                *bottom--   = tmp;
            }

        } else {
    	    InputPtrsType  uptr = ssGetInputPortSignalPtrs(S,INPORT);  
            creal_T	  *y    = (creal_T *)ssGetOutputPortSignal(S,OUTPORT) + (width-1);

	    while(width-- > 0) {
	        *y-- = *((creal_T *)(*uptr++));
	    }
        }
    }
}


static void mdlTerminate(SimStruct *S)
{
}


#include "dsp_cplxhs11.c"   

#ifdef	MATLAB_MEX_FILE   
#include "simulink.c"     
#else
#include "cg_sfun.h"      
#endif
