/**
 * The Paper Tape Project -- Font subproject
 * PaperTapeFont C Library
 *
 * (c) 2008 Sven Köppel
 *
 * This program is free software; you can redistribute
 * it and/or modify it under the terms of the GNU General
 * Public License as published by the Free Software
 * Foundation; either version 3 of the License, or (at
 * your option) any later version.
 *
 * This program is distributed in the hope that it will
 * be useful, but WITHOUT ANY WARRANTY; without even the
 * implied warranty of MERCHANTABILITY or FITNESS FOR A
 * PARTICULAR PURPOSE. See the GNU General Public License
 * for more details.
 *
 * You should have received a copy of the GNU General
 * Public License along with this program; if not, see
 * http://www.gnu.org/licenses/.
 *
 **/

#ifndef __PAPERTAPE_FONT_H__
#define __PAPERTAPE_FONT_H__

#include <stdlib.h>
#include <stdio.h>

/**
 * We use "char" in three situations:
 *   1. As normal (ASCII) characters/letters, like in    char ascii_id = 'a';
 *   2. As strings, like in                             char* line = "hello";
 *   3. As byte arrays, like in  unsigned char *bytes = { 0x12, 0x23, 0x45 };
 *
 * To make this a bit more clearer, here is a quite common typedef:
 **/
typedef unsigned char   byte_t;

/**
 * This is the structure of one link from the linked list. It represents exactly
 * one character, how it is punched on the papertape. It's called
 * PAPERTAPE_FONT_CHAR everywhere in the program, by using a typedef.
 *
 * The PAPERTAPE_FONT struct itself is nothing else than the start element of the
 * linked list. Therefore it's just the same data structure.
 **/
struct _papertape_font_char {
	char ascii_id;
	char *name;
	byte_t* bytes;
	int bytes_n;

	struct _papertape_font_char* next;
};

typedef struct _papertape_font_char PAPERTAPE_FONT_CHAR;
typedef struct _papertape_font_char PAPERTAPE_FONT;

/**
 * These defines are the names which are used in the Papertape font files
 * for the specific special characters.
 **/
#define PAPERTAPE_FONT_CHARACTER_SPACING_NAME   "character_spacing"
#define PAPERTAPE_FONT_WHITE_SPACE_NAME         "white_space"

/**
 * The content of this definition is written at the very first lines at every
 * papertape font file which is changed by the routines.
 *
 **/
#define PAPERTAPE_FONT_WRITE_FIRST_LINES \
	"The Paper Tape Project -- PAPERTAPE_FONT file.\n" \
	"The content of this file describes a paper tape font. You can edit it\n" \
	"with a text editor. Lines like this ones are comments.\n" \
	"See http://dev.technikum29.de/svn/paper-tape-project/\n" \
	"See this small key how the document is structured:"\
	"\n" \
	" bits     |identification\n" \
	" 123.45678|char/string\n" \
	"|   .     |\n"

/**
 * These definitions define characters which are used when writing papertape
 * files. They should not be changed unless the data format changes one day.
 **/
#define PAPERTAPE_FONT_WRITE_LOGICAL_1   '+'
#define PAPERTAPE_FONT_FEED_HOLE         '.'
#define PAPERTAPE_FONT_BORDER            '|'
/**
 * This is the magic id. It's quite very important.
 *
 **/
#define PAPERTAPE_FONT_SPECIAL_ID        (" =")

/**
 * The default schematics used for import and export. It should contain
 * the most important characters, like /[0-9a-z]/i (as regex)
 **/
#define PAPERTAPE_FONT_SCHEMATICS_DEFAULT "abcdefghijklmnopqrstuvwxyz0123456789"


// Create and load functions
#define papertape_font_new()    ((PAPERTAPE_FONT*)malloc(sizeof(PAPERTAPE_FONT)))
PAPERTAPE_FONT* papertape_font_new_from_file(const char* filename);
void papertape_font_load_file(PAPERTAPE_FONT* font, FILE* fh);
void papertape_font_load_schematics(PAPERTAPE_FONT* font, const char *schematics, const byte_t *contents, int content_len);
void papertape_font_destroy(PAPERTAPE_FONT* font);


// Read functions
byte_t* papertape_font_get_label(PAPERTAPE_FONT* font, const char* string, int *size);
int papertape_font_string_is_printable(PAPERTAPE_FONT *font, const char* string);
void papertape_font_dump(PAPERTAPE_FONT *font, FILE* fh);
PAPERTAPE_FONT_CHAR* papertape_font_low_get_char(PAPERTAPE_FONT* font, char ascii_id);
PAPERTAPE_FONT_CHAR* papertape_font_low_get_special(PAPERTAPE_FONT* font, const char* name);

// Write functions
PAPERTAPE_FONT_CHAR* papertape_font_set_char(PAPERTAPE_FONT* font, char ascii_id, const byte_t* bytes, int bytes_n);
PAPERTAPE_FONT_CHAR* papertape_font_set_special(PAPERTAPE_FONT* font, const char* name, const byte_t* bytes, int bytes_n);
int papertape_font_del_char(PAPERTAPE_FONT* font, char ascii_id);
int papertape_font_del_special(PAPERTAPE_FONT* font, const char* name);
int papertape_font_write_to_file(PAPERTAPE_FONT* font, FILE *fh);


#endif /* __PAPERTAPE_FONT_H__ */

