/*
 * src/font.c
 * https://gitlab.com/bztsrc/assetpack
 *
 * Copyright (C) 2024 bzt, MIT license
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to
 * deal in the Software without restriction, including without limitation the
 * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
 * sell copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL ANY
 * DEVELOPER OR DISTRIBUTOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
 * IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 *
 * @brief Handle font formats
 */

#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <setjmp.h>
#include <apck.h>
#include <libsfn.h>
#include "libsfn/bitmap.h"
#include "libsfn/vector.h"

void asc(char *ptr, int size);
void sfn(unsigned char *ptr, int size);
uint8_t *sfn_save(uint32_t *size);
void *my_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen);
extern sfnctx_t ctx;

/**
 * Decode a a font asset
 */
uint8_t *font_decode(char *filename, uint8_t *buf, uint64_t size, uint32_t *len)
{
    unsigned char *data = buf;
    char *e;
    int r;
    uint8_t *ret = NULL;

    if(!buf || !size || !len) return NULL;

    data[size] = 0;

    memset(&ctx, 0, sizeof(ctx));
    rs = 0; re = 0x10FFFF;
    r = 1; e = strrchr(filename, '.'); (void)e;
    if(data[0]=='S' && data[1]=='F' && data[2]=='N' && data[3]=='C') {
        if(!quiet) fprintf(stderr, "libsfn: file is a collection with multiple fonts. Extract fonts first.\n");
        r = 0;
    } else if(data[0]=='S' && data[1]=='F' && data[2]=='N' && data[3]=='2') {
        sfn(data, size);
    } else if(data[0]=='#' && data[1]==' ' && data[2]=='S' && data[3]=='c') {
        asc((char*)data, size);
    } else if(data[0]==0x72 && data[1]==0xB5 && data[2]==0x4A && data[3]==0x86) {
        psf(data, size);
    } else if(data[8]=='P' && data[9]=='F' && data[10]=='F' && data[11]=='2') {
        pff(data, size);
    } else if((data[0]=='M' && data[1]=='Z') || (!data[0] && (data[1] == 2 || data[1] == 3) && !data[5] && (data[6] > ' ' &&
        data[6] < 127))) {
        fnt(data, size);
    } else if(data[0]=='S' && data[1]=='T' && data[2]=='A' && data[3]=='R') {
        bdf((char*)data, size);
    } else if(data[0]==1 && data[1]=='f' && data[2]=='c' && data[3]=='p') {
        pcf(data, size);
    } else if(data[0]=='S' && data[1]=='p' && data[2]=='l' && data[3]=='i' && data[4]=='n') {
        sfd((char*)data, size);
    } else if(data[0]==0xE1 && data[1]==0xE6 && data[2]==0xD5 && data[3]==0x1A) {
        bmf(data, size);
    } else if(!memcmp(data, "KBnPbits", 8)) {
        kbits(data, size);
    } else if(!memcmp(data, "<?xml", 5) && my_memmem(data, size < 256 ? size : 256, "<kbits>", 7)) {
        kbitx((char*)data, size);
    } else if((data[0]>='0' && data[0]<='9') || (data[0]>='A' && data[0]<='F')) {
        hex((char*)data, size);
    } else if(e && !strcmp(e, ".yaff")) {
        yaff((char*)data, size);
    } else if(e && (e[1] == 'f' || e[1] == 'F') && e[2] >= '0' && e[2] <= '9' && e[3] >= '0' && e[3] <= '9') {
        raw(data, size, atoi(e + 2));
    } else if(ft2_read(data, size)) {
        ft2_parse();
    } else {
        r = 0;
    }
    if(!ctx.name) sfn_setstr(&ctx.name, filename, 0);
    if(r) {
        sfn_sanitize(-1);
        ret = sfn_save(len);
    }
    return ret;
}
