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

psF32 psMetadataItemParseF32(psMetadataItem *item
                            )
{
    switch (item->type) {
    case PS_DATA_F32:
        return item->data.F32;
    case PS_DATA_F64:
        // Assume it's OK to truncate to floating point from double
        return (float)item->data.F64;
    case PS_DATA_S32:
        // Promote to float
        return (float)item->data.S32;
    default:
        psError(PS_ERR_IO, true, "Item %s (%s) is not of floating point type (%x) --- treating as NaN.\n",
                item->name, item->comment, item->type);
        return NAN;
    }
}

psF64 psMetadataItemParseF64(psMetadataItem *item
                            )
{
    switch (item->type) {
    case PS_TYPE_F64:
        return item->data.F64;
    case PS_TYPE_F32:
        // Promote to double
        return (double)item->data.F32;
    case PS_TYPE_S32:
        // Promote to double
        return (double)item->data.S32;
    default:
        psError(PS_ERR_IO, true, "Item %s (%s) is not of double-precision floating point type (%x) "
                "--- treating as NaN.\n", item->name, item->comment, item->type);
        return NAN;
    }
}

psS32 psMetadataItemParseS32(psMetadataItem *item
                            )
{
    switch (item->type) {
    case PS_TYPE_S32:
        return item->data.S32;
    case PS_TYPE_F32:
        psLogMsg(__func__, PS_LOG_WARN, "Item %s (%s) should be S32, but is F32 --- converting.\n",
                 item->name, item->comment);
        return (int)item->data.F32;
    case PS_TYPE_F64:
        psLogMsg(__func__, PS_LOG_WARN, "Item %s (%s) should be S32, but is F64 --- converting.\n",
                 item->name, item->comment);
        return (int)item->data.F64;
    default:
        psError(PS_ERR_IO, true, "Item %s (%s) is not of integer type (%x) --- treating as zero.\n",
                item->name, item->comment, item->type);
        return 0;
    }
}

psString psMetadataItemParseString(psMetadataItem *item
                                  )
{
    switch (item->type) {
    case PS_DATA_STRING:
        return psMemIncrRefCounter(item->data.V);
    case PS_DATA_F32: {
            psString value = NULL;    // String to return
            psStringAppend(&value, "%f", item->data.F32);
            return value;
        }
    case PS_DATA_S32: {
            psString value = NULL;    // String to return
            psStringAppend(&value, "%d", item->data.S32);
            return value;
        }
    default:
        psError(PS_ERR_IO, true, "Item %s (%s) is not of string type (%x) --- treating as "
                "undefined.\n", item->name, item->comment, item->type);
        return psStringCopy("");
    }
}

