// See LICENSE  file for license details

#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
#include <stdint.h>

#include "common.h"
#include "image_info.h"
#include "path_ops.h"
#include "logging.h"
#include "options.h"


// Writes a buffer to a file in C source format
// Adds a matching .h if possible
//
bool file_c_output_write(const char * fname_base, const char * varname_in, int bank_num, int tile_count, int height_in_tiles) {

    char varname_withpath[MAX_PATH * 2];
    char filename_c[MAX_PATH * 2];
    char filename_h[MAX_PATH * 2];
    strcpy(varname_withpath, varname_in);
    strcpy(filename_c, fname_base);
    strcpy(filename_h, fname_base);
    strcat(filename_c, ".c");
    strcat(filename_h, ".h");

    // Fix up varname if needed to be usable in the C source file
    //
    // If varname arg wasn't specified it will be derived from
    // filename out and may include path that needs to be stripped.
    char * varname = (char *)get_filename_from_path(varname_withpath);
    char * ch = varname;
    while (*ch != '\0') {
        if ((*ch == ' ') || (*ch == '-')) *ch = '_';
        ch++;
    }

    VERBOSE("Writing C format to: %s, %s\n", filename_c, filename_h);

    // === C Source output ===
    FILE * file_out_c = fopen(filename_c, "w");
    if (file_out_c) {

        fprintf(file_out_c,
            "#include <gbdk/platform.h>\n"
            "#include <gbdk/incbin.h>\n\n");

        // If Bank Num is set add pragma
        if (bank_num != BANK_NUM_UNSET) {
            fprintf(file_out_c, "#pragma bank %d\n", bank_num);
        }
        fprintf(file_out_c, "BANKREF(%s)\n\n", varname);

        fprintf(file_out_c,
            "#include <gbc_hicolor.h>\n"
            "\n"
            "// Generated by png2hicolorgb\n"
            "\n"
            "// Note: filepath is relative to the working directory of the tool that is calling it (often a makefile's working directory), NOT to the file it's being included into.\n"
            "\n"
            "INCBIN(%s_tiles,   \"%s.til\")\n"
            "INCBIN(%s_map,     \"%s.map\")\n"
            "INCBIN(%s_attr,    \"%s.atr\")\n"
            "INCBIN(%s_palette, \"%s.pal\")\n"
            "\n"
            "INCBIN_EXTERN(%s_tiles)\n"
            "INCBIN_EXTERN(%s_map)\n"
            "INCBIN_EXTERN(%s_attr)\n"
            "INCBIN_EXTERN(%s_palette)\n"
            "\n"
            "const hicolor_data %s_data = {\n"
            "    .tile_count      = %du,\n"
            "    .height_in_tiles = %du,\n"
            "    .p_tiles         = %s_tiles,\n"
            "    .p_map           = %s_map,\n"
            "    .p_attribute_map = %s_attr,\n"
            "    .p_palette       = %s_palette\n"
            "};\n"
            "\n"
        ,varname, fname_base,
         varname, fname_base,
         varname, fname_base,
         varname, fname_base,
         varname, varname, varname, varname,
         varname,
         tile_count, height_in_tiles,
         varname, varname, varname, varname
        );
        fclose(file_out_c);
    } else {
        printf("Error: Failed to open output file: %s\n", filename_c);
        return false;
    }

    // === Header output ===
    FILE * file_out_h = fopen(filename_h, "w");
    if (file_out_h) {

        fprintf(file_out_h, "#include <gbdk/platform.h>\n\n");
        fprintf(file_out_h, "BANKREF_EXTERN(%s)\n\n", varname);

        fprintf(file_out_h,
            "#ifndef __%s_h_\n"
            "#define __%s_h_\n"
            "\n"
            "#include <gbc_hicolor.h>\n"
            "\n"
            "// Generated by png2hicolorgb\n"
            "\n"
            "extern const hicolor_data %s_data;\n"
            "\n"
            "#endif\n"
            "\n"
            ,varname, varname,
             // varname, varname, varname, varname,
             varname
        );
        fclose(file_out_h);
    } else {
        printf("Error: Failed to open output file: %s\n", filename_h);
        return false;
    }

    return true;
}
