#include "ptex_filter_wrapper.h"
#include <Ptexture.h>

extern "C" {

PtexFilterHandle ptex_filter_create(PtexTextureHandle texture, const PtexFilterOptions* opts) {
    Ptex::PtexTexture* tex = static_cast<Ptex::PtexTexture*>(texture);
    if (!tex || !opts) return nullptr;

    Ptex::PtexFilter::Options ptex_opts;
    ptex_opts.filter = static_cast<Ptex::PtexFilter::FilterType>(opts->filter);
    ptex_opts.lerp = opts->lerp;
    ptex_opts.sharpness = opts->sharpness;
    ptex_opts.noedgeblend = opts->noedgeblend != 0;

    return Ptex::PtexFilter::getFilter(tex, ptex_opts);
}

void ptex_filter_eval(
    PtexFilterHandle filter,
    float* result,
    int32_t first_channel,
    int32_t num_channels,
    int32_t face_id,
    float u, float v,
    float dudx, float dvdx,
    float dudy, float dvdy
) {
    Ptex::PtexFilter* f = static_cast<Ptex::PtexFilter*>(filter);
    if (f && result) {
        f->eval(result, first_channel, num_channels, face_id, u, v, dudx, dvdx, dudy, dvdy);
    }
}

void ptex_filter_release(PtexFilterHandle filter) {
    Ptex::PtexFilter* f = static_cast<Ptex::PtexFilter*>(filter);
    if (f) {
        f->release();
    }
}

PtexTextureHandle ptex_texture_open(const char* filename, char** error_str) {
    Ptex::String error;
    Ptex::PtexTexture* tex = Ptex::PtexTexture::open(filename, error);
    
    if (!tex && error_str) {
        *error_str = strdup(error.c_str());
    }
    
    return tex;
}

void ptex_texture_release(PtexTextureHandle texture) {
    Ptex::PtexTexture* tex = static_cast<Ptex::PtexTexture*>(texture);
    if (tex) {
        tex->release();
    }
}

int32_t ptex_texture_num_channels(PtexTextureHandle texture) {
    Ptex::PtexTexture* tex = static_cast<Ptex::PtexTexture*>(texture);
    return tex ? tex->numChannels() : 0;
}

}
