#include <stdio.h>
#include "pslib.h"


#define FLIP_X_CASE(TYPENAME,TYPE) \
case TYPENAME: \
for (int i = 0; i < image->numRows; i++) { \
    for (int j = 0; j < image->numCols; j++) { \
        output->data.TYPE[i][j] = image->data.TYPE[i][image->numCols - j - 1]; \
    } \
} \
break;

// Return a flipped image in x
psImage *psImageFlipX(psImage *image    // Image to flip
                     )
{
    psImage *output = psImageAlloc(image->numCols, image->numRows, image->type.type); // Output image
    switch(image->type.type) {
        FLIP_X_CASE(PS_TYPE_U8,  U8);
        FLIP_X_CASE(PS_TYPE_U16, U16);
        FLIP_X_CASE(PS_TYPE_U32, U32);
        FLIP_X_CASE(PS_TYPE_U64, U64);
        FLIP_X_CASE(PS_TYPE_S8,  S8);
        FLIP_X_CASE(PS_TYPE_S16, S16);
        FLIP_X_CASE(PS_TYPE_S32, S32);
        FLIP_X_CASE(PS_TYPE_S64, S64);
        FLIP_X_CASE(PS_TYPE_F32, F32);
        FLIP_X_CASE(PS_TYPE_F64, F64);
        FLIP_X_CASE(PS_TYPE_C32, C32);
        FLIP_X_CASE(PS_TYPE_C64, C64);
    default:
        psFree(output);
        psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Unknown type for input image: %x\n", image->type.type);
        return NULL;
    }

    return output;
}


#define FLIP_Y_CASE(TYPENAME,TYPE) \
case TYPENAME: \
for (int i = 0; i < image->numRows; i++) { \
    for (int j = 0; j < image->numCols; j++) { \
        output->data.TYPE[i][j] = image->data.TYPE[image->numRows - i - 1][j]; \
    } \
} \
break;

// Return a flipped image in y
psImage *psImageFlipY(psImage *image    // Image to flip
                     )
{
    psImage *output = psImageAlloc(image->numCols, image->numRows, image->type.type); // Output image
    switch(image->type.type) {
        FLIP_Y_CASE(PS_TYPE_U8,  U8);
        FLIP_Y_CASE(PS_TYPE_U16, U16);
        FLIP_Y_CASE(PS_TYPE_U32, U32);
        FLIP_Y_CASE(PS_TYPE_U64, U64);
        FLIP_Y_CASE(PS_TYPE_S8,  S8);
        FLIP_Y_CASE(PS_TYPE_S16, S16);
        FLIP_Y_CASE(PS_TYPE_S32, S32);
        FLIP_Y_CASE(PS_TYPE_S64, S64);
        FLIP_Y_CASE(PS_TYPE_F32, F32);
        FLIP_Y_CASE(PS_TYPE_F64, F64);
        FLIP_Y_CASE(PS_TYPE_C32, C32);
        FLIP_Y_CASE(PS_TYPE_C64, C64);
    default:
        psFree(output);
        psError(PS_ERR_BAD_PARAMETER_TYPE, true, "Unknown type for input image: %x\n", image->type.type);
        return NULL;
    }

    return output;
}
