#include "list.h"

#define IWU_PATCH_OK                    0
#define IWU_PATCH_NOMEM                 1
#define IWU_PATCH_CANTOPEN              2
#define IWU_PATCH_FILE_CORRUPT          3
#define IWU_PATCH_FILE_TOO_LARGE        4
#define IWU_PATCH_BAD_INDEX             5
#define IWU_PATCH_NO_IW_ENVIRON         6
#define IWU_PATCH_NO_DEFAULT_VENDOR     7
#define IWU_PATCH_NO_VENDOR_PATCHES     8
#define IWU_PATCH_NO_DIR                9
#define IWU_PATCH_FILE_VERSION_MISMATCH 10
#define IWU_PATCH_CANTFIND              11

#define IWU_PATCH_DIR_LEN 80
#define IWU_PATCH_FILENAME_LEN 20

#define IWU_PATCH_LOADED        BIT0
#define IWU_PATCH_NEEDED        BIT1
#define IWU_PATCH_LOCKED        BIT2
#define IWU_PATCH_EDITABLE      BIT3

struct iwu_fast_patch {
    union {
	struct {
	    unsigned char program;
	    unsigned char bank;
	} h;
	unsigned short bank_program;
    } id;
    unsigned char flags;
    struct iw_patch RFAR *p;
    unsigned long ud;
};

struct fff_file {
    struct iw_patch RFAR *first_patch;
    unsigned char RFAR *pbuf; /* patch info */
    unsigned long plen; /* patch info length */
    int npatches;       /* number of patches in quick search list */
    struct iwu_fast_patch RFAR *patches;
};

struct patch_lib {
    struct patch_lib RFAR*next;
    char patch_filename[IWU_PATCH_FILENAME_LEN];
    char patch_dir[IWU_PATCH_DIR_LEN];
    struct list fff_list;
};

/* rom header */
struct rom_hdr {
/* 000 */    char iwave[8];
//              "INTRWAVE"
/* 008 */    unsigned char rom_hdr_revision;
//              rom header revision
/* 009 */    unsigned char series_number;
//              series number (for multi chip rom sets or 0)
/* 010 */    char series_name[16];
//              series name for identifying a chip as part of a collection.
/* 026 */    char date[10];
//              rom creation date. i.e. 03/13/1995
/* 036 */    unsigned short vendor_revision_major;
//              revision number (used by manufacturer)
/* 038 */    unsigned short vendor_revision_minor;
//              revision number (used by manufacturer)
/* 040 */    unsigned long rom_size;
//              size of this rom chip in bytes
/* 044 */    char copyright[128];
//              vendors copyright message.  NUL terminated.
/* 172 */    char vendor_name[64];
//              vendors name or information.  NUL terminated.
/* 236 */    char rom_description[128];
//              text description of ROM.  NUL terminated.
/* 364 */    char pad[147];
//              padding - must be zero filled
/* 511 */    unsigned char csum;
//              checksum of header
};

extern struct patch_lib RFAR*plib;

struct iwu_fast_patch RFAR *iwu_find_patch(int program, int bank, struct patch_lib RFAR *RFAR *ppl);
int iwu_unload_patch(int prog, int bank);
int iwu_get_patch_config(void);
char *iwu_error_str(int error);
void iwu_clear_marked_patches(void);
int iwu_load_patch(int prog, int bank, char RFAR *diskbuff, int bsize, void (*free_memory_cb)(struct iwu_fast_patch RFAR *fp, int attempt), int load_as_8);
void iwu_load_marked_patches(char RFAR *diskbuff, int bsize, void (*free_memory_cb)(struct iwu_fast_patch RFAR *, int attempt), int load_as_8);
void iwu_mark_patch(int program, int bank);
void iwu_unmark_patch(int program, int bank);
void iwu_unload_all_patches(void);
int iwu_fff_load(struct patch_lib RFAR *pl);
void iwu_fff_unload(struct patch_lib RFAR *pl);
