// start und end time werden noch nicht auf dimensionierung geprueft

// file       5
// keyboard   7
// dosmem    10
// d_list    15
// l_level   20
// vesa      25
// pcx       30
// bild      35
// win_raw   40
// parser    45
// button    50
// tprint    55
// tdispatc  60
// updatef   65
// request   70
// help      75
// edit      85
// tool     100
// main     500
# ifndef ERROR_H
#  define ERROR_H

# ifdef __cplusplus
 extern "C" {
# endif


# include <stdio.h>
# include <stdarg.h>
# include <time.h>

# include "standard.h"

/* Exportierte Funktionen */
#define FUNCTION_MAX_DEPTH 1000
#define MAX_PROTOCOLL_LENGTH 1000

#define ERROR_NUMBER_EXACT 1
#define ERROR_NUMBER_HIGHER 2
#define ERROR_SPECIFIC 3

#define E_VERBOSE_NONE     0
#define E_VERBOSE_LOW      1
#define E_VERBOSE_STANDARD 2
#define E_VERBOSE_HIGH     3
// in t_printf()
// E_VERBOSE_NONE means print allways


extern T_INT e_verbose;
extern T_INT tool_error;
extern T_INT protocol_variant;
extern T_INT function_history;
extern T_INT function_timing;
extern T_INT error_function_position[FUNCTION_MAX_DEPTH];
extern T_INT error_this_function[FUNCTION_MAX_DEPTH];
extern T_PVOID error_function_string[FUNCTION_MAX_DEPTH];
extern clock_t start_time[FUNCTION_MAX_DEPTH];
extern clock_t end_time[FUNCTION_MAX_DEPTH];
extern T_CHAR error_protocoll_string[MAX_PROTOCOLL_LENGTH];
extern T_INT function_level;
extern T_INT level_max;
extern T_INT current_error_level; // show level higher or equal than this value
extern T_INT error_level_this_function[FUNCTION_MAX_DEPTH];

#define FUNCTION_ENTRY 0
#define FUNCTION_LEAVE 1
#define FUNCTION_PROTOCOLL 2

T_VOID tool_exit(T_INT tool_error);
T_VOID init_error(T_VOID);
T_VOID error_function_protokoll(T_INT wo,clock_t t);
T_VOID error_protokoll(T_PCHAR format, ...);
T_VOID t_printf(T_INT verbosity_level,T_PUCHAR acString,...);
extern T_INT protocol_variant;

#ifdef T_DEBUG_ALLOW
#define T_DEBUG_ENTRY(NAME,LEVEL)                                     \
{                                                                     \
 start_time[function_level]=clock();                                          \
 if (function_level<FUNCTION_MAX_DEPTH)                               \
 {                                                                    \
  error_function_position[function_level]=0;                          \
  error_this_function[function_level]=0;                              \
  error_level_this_function[function_level]=LEVEL;                    \
  error_function_string[function_level]=NAME;                         \
  level_max=0;                                                        \
 }                                                                    \
 else                                                                 \
 {                                                                    \
  level_max=1;                                                        \
 }                                                                    \
 if (protocol_variant==ERROR_NUMBER_HIGHER)                           \
  if (current_error_level<=error_level_this_function[function_level]) \
   error_function_protokoll(FUNCTION_ENTRY,end_time[function_level]-start_time[function_level]);      \
 if (protocol_variant==ERROR_NUMBER_EXACT)                            \
  if (current_error_level==error_level_this_function[function_level]) \
   error_function_protokoll(FUNCTION_ENTRY,end_time[function_level]-start_time[function_level]);      \
 if (protocol_variant==ERROR_SPECIFIC)                                \
   error_function_protokoll(FUNCTION_ENTRY,end_time[function_level]-start_time[function_level]);      \
 function_level++;                                                    \
}
#define T_DEBUG_FUNCTION_POSITION(NUMMER)                             \
{                                                                     \
 if (function_level-1<FUNCTION_MAX_DEPTH)                             \
 {                                                                    \
  error_function_position[function_level-1]=NUMMER;                   \
 }                                                                    \
}
#define T_DEBUG_SET_THIS_FUNCTION_ERROR(ERROR_TYPE)                   \
{                                                                     \
 if (function_level-1<FUNCTION_MAX_DEPTH)                             \
 {                                                                    \
  error_this_function[function_level-1]=ERROR_TYPE;                   \
 }                                                                    \
}
#define T_DEBUG_LEAVE                                                 \
{                                                                     \
 function_level--;                                                    \
 end_time[function_level]=clock();                                                    \
 if (level_max==1)                                                    \
 {                                                                    \
  if (function_level<FUNCTION_MAX_DEPTH)                              \
  {                                                                   \
   level_max=0;                                                       \
  }                                                                   \
 }                                                                    \
 if (protocol_variant==ERROR_NUMBER_HIGHER)                           \
  if (current_error_level<=error_level_this_function[function_level]) \
   error_function_protokoll(FUNCTION_LEAVE,end_time[function_level]-start_time[function_level]);      \
 if (protocol_variant==ERROR_NUMBER_EXACT)                            \
  if (current_error_level==error_level_this_function[function_level]) \
   error_function_protokoll(FUNCTION_LEAVE,end_time[function_level]-start_time[function_level]);      \
 if (protocol_variant==ERROR_SPECIFIC)                                \
   error_function_protokoll(FUNCTION_LEAVE,end_time[function_level]-start_time[function_level]);      \
}
// Beispiel
// T_DEBUG_PROTOCOLL(("i=%i\nbreite=%i\nhoehe=%i",i,ein_font->zeichen[i].breite,ein_font->zeichen[i].hoehe))
#define T_DEBUG_PROTOCOLL(ARGS)                                       \
{                                                                     \
 error_protokoll ARGS;                                                \
}

#else
#define T_DEBUG_ENTRY(NAME,LEVEL)
#define T_DEBUG_SET_THIS_FUNCTION_ERROR(ERROR_TYPE)
#define T_DEBUG_FUNCTION_POSITION(NUMMER)
#define T_DEBUG_LEAVE
#define T_DEBUG_PROTOCOLL(ARGS)
#endif



// no errors 0 - 9 (T_OK ... )
/* tool errors */
# define TOOL_INIT_ERROR                   011
# define TOOL_NO_VESA_MODE_ACTIVE          012

/* file errors */
# define FILE_OPEN_ERROR                   100
# define FILE_NOT_CLOSED                   101
# define FILE_ALREADY_OPEN                 102
# define FILE_REWIND_ERROR                 103
# define FILE_FORWARD_ERROR                104
# define FILE_NO_HANDLE                    105
# define FILE_READ_ERROR                   106
# define FILE_DIRECTORY_ERROR              107

/* vesa errors */
# define VESA_NOT_INITIALIZED              200
# define VESA_MODE_NOT_FOUND               201
# define VESA_NOTHING_DONE                 202
# define VESA_DRIVER_ERROR                 203
# define VESA_NO_MOUSEDRIVER_FOUND         204
# define VESA_NO_MOUSE_INSTALLED           205
# define VESA_MOUSE_POSITION_OUT_OF_SCREEN 206
# define VESA_NO_RECTANGLE                 207
# define VESA_NO_VESA_MODE_FOUND           208
# define VESA_FAILED_SET_BANKED            209
# define VESA_UNKNOWN_VESA_ERROR           210
# define VESA_NO_DOS_MEMORY                211
# define VESA_NO_SVGALIB                   212

/* generic errors */
# define GENERIC_MEMORY_NOT_AVAILABLE      300
# define GENERIC_NO_BACKGROUND             301
# define GENERIC_TEXT_TO_LONG              304

/* window errors */
# define WINDOW_NOT_AVAILABLE              400
# define WINDOW_DOUBLE_ID                  401
# define WINDOW_OPEN_ERROR                 402
# define WINDOW_NO_AREA_MEMORY             403
# define WINDOW_NO_GRAPHICS_MODE_ACTIVE    404

/* button errors */
# define BUTTON_NOT_PRESSED                500
# define BUTTON_DOUBLE_ID                  501
# define BUTTON_NOT_AVAILABLE              502
# define BUTTON_NO_MEM_BILD                503
# define BUTTON_DEFAULT_BITMAPS_NOT_FOUND  504
# define BUTTON_LOAD_BITMAP_ERROR          505
# define NO_VALUE_FOR_CHECK_BUTTON         506
/* list errors */
# define LIST_ELEMENT_NOT_FOUND            600

/* parse errors */
# define PARSE_PARSE_ERROR                 700
# define PARSE_INTEGER_OVERFLOW            701
# define PARSE_FILE_END                    702
# define PARSE_PARSE_FILE_NOT_FOUND        703
# define PARSE_NO_TYPE_FOUND               704
# define PARSE_NO_NUMBER                   705
# define PARSE_NO_STRING                   706
# define PARSE_NO_ASCII                    707
# define PARSE_NO_FILE_OPEN                708
# define PARSE_PRE_PROCESS_ERROR           709
# define PARSE_DEFINE_ERROR                710


/* pcx errors */
# define PCX_FILE_END                      800
# define PCX_LINE_TO_LONG                  801

/* help errors */
# define HELP_WINDOW_NOT_OPEN              900
# define HELP_WINDOW_ALLREADY_OPEN         901
# define HELP_FILE_NOT_FOUND               902
# define HELP_WINDOW_NOT_OPENED            903
# define HELP_BUTTON_CREATION_FAILED       904
# define HELP_BUTTON_CANT_FIND_MYSELF      905
# define HELP_BUTTON_NO_USER_FUNCTION      906

/* keyboard errors */
# define KEY_NULL_POUNTER                 1000
# define KEY_BAD_INDEX                    1001
# define KEY_BREAK                        1002
/* edit errors */
#define EDIT_WINDOW_WITH_DESTRUCTOR       1100
#define EDIT_WINDOW_NO_BUTTON_SPACE       1101
#define EDIT_BUTTON_CREATION_FAILED       1102
#define EDIT_NO_LOG_WINDOW                1103

/* list errors */
#define LIST_OBJECT_NOT_FOUND             1200

# define VESA_DATEN_FREIGEGEBEN (1*1)
# define VESA_MODUS_DATEN_FREIGEGEBEN (1*10)
# define VESA_MODUS_UND_DATEN_FREIGEGEBEN (VESA_DATEN_FREIGEGEBEN+VESA_MODUS_DATEN_FREIGEGEBEN)

# ifdef __cplusplus
}
# endif

#endif
