/*
 *  Copyright (c) 2010 The WebM project authors. All Rights Reserved.
 *
 *  Use of this source code is governed by a BSD-style license
 *  that can be found in the LICENSE file in the root of the source
 *  tree. An additional intellectual property rights grant can be found
 *  in the file PATENTS.  All contributing project authors may
 *  be found in the AUTHORS file in the root of the source tree.
 */


/*!\file
 * \brief Provides the high level interface to wrap decoder algorithms.
 *
 */
#include <stdarg.h>
#include "vpx/vpx_integer.h"
#include "vpx/internal/vpx_codec_internal.h"
#include "vpx_version.h"

#define SAVE_STATUS(ctx,var) (ctx?(ctx->err = var):var)

int vpx_codec_version(void)
{
    return VERSION_PACKED;
}


const char *vpx_codec_version_str(void)
{
    return VERSION_STRING_NOSP;
}


const char *vpx_codec_version_extra_str(void)
{
    return VERSION_EXTRA;
}


const char *vpx_codec_iface_name(vpx_codec_iface_t *iface)
{
    return iface ? iface->name : "<invalid interface>";
}

const char *vpx_codec_err_to_string(vpx_codec_err_t  err)
{
    switch (err)
    {
    case VPX_CODEC_OK:
        return "Success";
    case VPX_CODEC_ERROR:
        return "Unspecified internal error";
    case VPX_CODEC_MEM_ERROR:
        return "Memory allocation error";
    case VPX_CODEC_ABI_MISMATCH:
        return "ABI version mismatch";
    case VPX_CODEC_INCAPABLE:
        return "Codec does not implement requested capability";
    case VPX_CODEC_UNSUP_BITSTREAM:
        return "Bitstream not supported by this decoder";
    case VPX_CODEC_UNSUP_FEATURE:
        return "Bitstream required feature not supported by this decoder";
    case VPX_CODEC_CORRUPT_FRAME:
        return "Corrupt frame detected";
    case  VPX_CODEC_INVALID_PARAM:
        return "Invalid parameter";
    case VPX_CODEC_LIST_END:
        return "End of iterated list";
    }

    return "Unrecognized error code";
}

const char *vpx_codec_error(vpx_codec_ctx_t  *ctx)
{
    return (ctx) ? vpx_codec_err_to_string(ctx->err)
           : vpx_codec_err_to_string(VPX_CODEC_INVALID_PARAM);
}

const char *vpx_codec_error_detail(vpx_codec_ctx_t  *ctx)
{
    if (ctx && ctx->err)
        return ctx->priv ? ctx->priv->err_detail : ctx->err_detail;

    return NULL;
}


vpx_codec_err_t vpx_codec_destroy(vpx_codec_ctx_t *ctx)
{
    vpx_codec_err_t res;

    if (!ctx)
        res = VPX_CODEC_INVALID_PARAM;
    else if (!ctx->iface || !ctx->priv)
        res = VPX_CODEC_ERROR;
    else
    {
        if (ctx->priv->alg_priv)
            ctx->iface->destroy(ctx->priv->alg_priv);

        ctx->iface = NULL;
        ctx->name = NULL;
        ctx->priv = NULL;
        res = VPX_CODEC_OK;
    }

    return SAVE_STATUS(ctx, res);
}


vpx_codec_caps_t vpx_codec_get_caps(vpx_codec_iface_t *iface)
{
    return (iface) ? iface->caps : 0;
}


vpx_codec_err_t vpx_codec_control_(vpx_codec_ctx_t  *ctx,
                                   int               ctrl_id,
                                   ...)
{
    vpx_codec_err_t res;

    if (!ctx || !ctrl_id)
        res = VPX_CODEC_INVALID_PARAM;
    else if (!ctx->iface || !ctx->priv || !ctx->iface->ctrl_maps)
        res = VPX_CODEC_ERROR;
    else
    {
        vpx_codec_ctrl_fn_map_t *entry;

        res = VPX_CODEC_ERROR;

        for (entry = ctx->iface->ctrl_maps; entry && entry->fn; entry++)
        {
            if (!entry->ctrl_id || entry->ctrl_id == ctrl_id)
            {
                va_list  ap;

                va_start(ap, ctrl_id);
                res = entry->fn(ctx->priv->alg_priv, ctrl_id, ap);
                va_end(ap);
                break;
            }
        }
    }

    return SAVE_STATUS(ctx, res);
}
