#include <cstdio>
#include <string>

using namespace std;

size_t fsize(FILE* file);
bool fexists(const char* filename);
bool encode_file(FILE* infile, FILE* outfile, const char* varname);
void print_usage()
{
    printf("Usage: encode_file <infile> [<varname> [<outfile>]]\n");
}

int main(int argc, char** argv)
{
    int retval = EXIT_SUCCESS;
    FILE* infile = NULL;
    FILE* outfile = NULL;
    string inname;
    string outname;
    string varname;
    if (argc < 2)
    {
        print_usage();
        retval = EXIT_FAILURE;
        goto exit_main;
    }
    inname = argv[1];
    if (argc < 3)
        varname = "varname";
    else
        varname = argv[2];
    if (argc > 3)
        outname = argv[3];
    else
        outname = inname + ".cpp";

    if (!fexists(argv[1]))
    {
        fprintf(stderr, "File '%s' does not exist\n", argv[1]);
        retval = EXIT_FAILURE;
        goto exit_main;
    }
    if (!stricmp(inname.c_str(), outname.c_str()))
    {
        fprintf(stderr, "Not allowed to specify same in and out files");
        retval = EXIT_FAILURE;
        goto exit_main;
    }

    infile = fopen(inname.c_str(), "rb");
    if (!infile)
    {
        retval = EXIT_FAILURE;
        goto exit_main;
    }
    outfile = fopen(outname.c_str(), "w");
    if (!outfile)
    {
        retval = EXIT_FAILURE;
        goto exit_main;
    }

    encode_file(infile, outfile, varname.c_str());

exit_main:
    if (infile)
        fclose(infile);
    if (outfile)
        fclose(outfile);
    return retval;
}

size_t fsize(FILE* file)
{
    size_t pos = ftell(file);
    fseek(file, 0, SEEK_END);
    size_t len = ftell(file);
    fseek(file, pos, SEEK_SET);
    return len;
}

bool fexists(const char* filename)
{
    FILE* file = fopen(filename, "r");
    if (!file)
        return false;
    fclose(file);
    return true;
}

bool encode_file(FILE* infile, FILE* outfile, const char* varname)
{
    size_t x, len;
    len = fsize(infile);
    fprintf(outfile, "size_t sizeof%s = %d;\n", varname, len);
    fprintf(outfile, "unsigned char %s[] = {\n", varname);
    for (x = 0; x < len; ++x)
    {
        int ch = fgetc(infile);
        fprintf(outfile, "0x%02x,", ch);
        if (x % 20 == 19)
            fprintf(outfile, "//%d\n", x+1);
    }

    fprintf(outfile, "\n};\n");
    return true;
}
