#ifndef STRUCT_H
#define STRUCT_H
//-------------------------------------
//
// SuperCode (c)1996 by T.Kühn
//
// Programmiersprache:	ANSI-C
// Projektstart:			27.12.94
//
//-------------------------------------

#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <exec/types.h>
#include <intuition/screens.h>
#include <dos/dos.h>

#define CATCOMP_NUMBERS
#include <catalogs/loc.h>


//*************************************
//
// DEFINES
//
//*************************************

#define LibVersion	37

#define TAGS			struct TagItem
#define TAG_SUB(x)	TAG_MORE,(ULONG)(x)
#define FINDLEN		(40)

#define DNAME			(30)
#define DPATH			(130)
#define DLEN			(DPATH+DNAME)
#define FONTNAMESIZE	(40)

#define TAGS			struct TagItem
#define TAG_SUB(x)	TAG_MORE,(ULONG)(x)

#define CTRL			(IEQUALIFIER_CONTROL)
#define SHFT			(IEQUALIFIER_LSHIFT | IEQUALIFIER_RSHIFT | IEQUALIFIER_CAPSLOCK)
#define AMI				(IEQUALIFIER_LCOMMAND | IEQUALIFIER_RCOMMAND)
#define ALT				(IEQUALIFIER_LALT | IEQUALIFIER_RALT)

#define blitz(x)		(*(UWORD*)0xdff180)=(x)

#define MIN(a,b)		((a<b)?a:b)
#define MAX(a,b)		((a>b)?a:b)

//
//*************************************



//*************************************


//-------------------------------------
// Main
//-------------------------------------
#define ASK_EXIT		(1<<0)
#define ASK_AGAIN		(1<<1)
#define ASK_CONT		(1<<2)
#define ASK_SELECT	(1<<3)
#define ASK_YES		(1<<4)
#define ASK_NO			(1<<5)
#define ASK_OK			(1<<6)
#define ASK_ABORT		(1<<7)
#define ASK_SAVE		(1<<8)

#define ASK_END		(9)

extern BOOL exit_flag;

ULONG display_error(ULONG error,ULONG ask ...);
void Quit();


//-------------------------------------

#define MAX_FONTNAME				(128)
#define MAX_PUBSCREENNAME		(139)


//-------------------------------------
// Libs / Mem / Lists
//-------------------------------------
#define NT_TRY			(NT_USER-1)
#define NT_Menu		(NT_USER-2)
#define NT_SCORE		(NT_USER-3)

#define Empty(x)		( ((x)->lh_TailPred) == (struct tkNode *)(x) )
#define LNext(x)		( (APTR)(x).ln_Succ )
#define LPrev(x)		( (APTR)(x).ln_Pred )
#define LLast(x)		( (APTR)(x).ln_Succ->ln_Succ == 0 )
#define LFrst(x)		( (APTR)(x).ln_Pred->ln_Pred == 0 )

struct tkNode
{
	struct	tkNode *ln_Succ;
	struct	tkNode *ln_Pred;
	UBYTE		ln_Type;
	BYTE		ln_Pri;
	char		*ln_Name;
	void		*ln_user;
};

struct tkList
{
	struct	tkNode *lh_Head;
	struct	tkNode *lh_Tail;
	struct	tkNode *lh_TailPred;
	UBYTE 	lh_Type;
	UBYTE		lh_Pad;
	UWORD		lh_Numb;
	BOOL		Sort;
	struct	tkNode *lh_LstNode;
	struct	tkNode *lh_CurNode;
	void		(*lh_Free)()
};

extern struct Library *GadToolsBase,*IntuitionBase,*GfxBase,*WorkbenchBase,*CxBase,*KeymapBase,*LocaleBase,*UtilityBase,*IFFParseBase,*AslBase;

VOID Lib_Init();
VOID Lib_Free();
VOID Lib_Open(struct Library **Base,UBYTE *Name,ULONG Version);
VOID Lib_Close(struct Library **Base);

UBYTE *Memory_Alloc(long Size);
UBYTE *MemGfx_Alloc(long Size);
VOID Memory_Free(UBYTE **Mem);

VOID List_Init(struct tkList *List,ULONG type,void (*Func)() );
VOID List_AddTail(struct tkList *List,struct tkNode *Node);
VOID List_AddSort(struct tkList *List,struct tkNode *Node,long (*Func)(const void*,const void*));
VOID List_Remove(struct tkList *List,APTR Node);
VOID List_Free(struct tkList *List);
LONG List_FindNum(struct tkList *List,APTR Ptr,UBYTE *String);
APTR List_FindPtr(struct tkList *Liste,LONG Num,UBYTE *String);
LONG List_StrCmp(struct tkNode *Node1,struct tkNode *Node2);
LONG List_FuncCmp(struct FuncItem *Func1,struct FuncItem *Func2);
VOID List_QuickSort(struct tkNode **Array,register LONG Left,register LONG Right,LONG (*Func)(const void*,const void*));
VOID List_Sort(struct tkList *List,long (*Func)(const void*,const void*));
VOID List_DoAll(struct tkList *List,long (*Func)(const void*,APTR data),APTR data);

//-------------------------------------


//-------------------------------------
// Messages
//-------------------------------------
extern struct MsgPort *Port_Win,*Port_Wb;

ULONG wait_mask(ULONG mask);

VOID MsgPort_Init();
VOID MsgPort_Free();

VOID Command_Menu(struct Menu *Menu,LONG Code);
VOID Msg_GetWin();
VOID Msg_GetWb();
VOID Msg_GetCx();
VOID Wait_All();
VOID Draw_Border(struct WinBlk *Blk,struct GadInfo *Info);
VOID Draw_NextBorder(struct GadInfo *Info);
//-------------------------------------


//-------------------------------------
// Screen
//-------------------------------------
#define LIKE_WORKBENCH	(-1)

struct tkFont
{
	struct	TextFont *font;
	struct	TextAttr attr;
	UBYTE		fontname[MAX_FONTNAME+2];
};

struct tkScreen
{
	WORD					Width,Height,Depth;	// Screen-Defines
	ULONG					Mode;
	ULONG					OverScan;
	BOOL					Public;
	BOOL					Private;
	UBYTE					PubName[MAX_PUBSCREENNAME+2];

	struct tkFont		tkfont;
	struct Screen		*Scrn;
	BOOL					FlgOwn;
	BOOL					FlgWB;
	BOOL					FlgPublic;
	BOOL					FlgPrivate;

	APTR					Visual;
	struct DrawInfo	*DrawInfo;
	LONG					Xmul,Ymul;
	LONG					Xres,Yres;
};

#define MAX_COL	(16)

extern UWORD Reg_Col[MAX_COL+2];
extern UBYTE PUB_WB[];
extern struct tkScreen Scrn;

VOID	Screen_Init(struct tkScreen *Scr);
ULONG	Screen_Open(struct tkScreen *Scr);
ULONG	Screen_Close(struct tkScreen *Scr);
VOID Font_Open(struct tkFont *tkfont);
VOID Font_Close(struct tkFont *tkfont);

//-------------------------------------


//-------------------------------------
// Menus.c
//-------------------------------------
struct tkNewMenu
{
	UBYTE		Type;
	ULONG		LocText;
	VOID		(*Func)();
	BOOL		*Toggle;
	UBYTE		CommKey[2];
};

struct tkMenu
{
	struct	tkNode Node;
	struct	Menu *Menu;
	struct	NewMenu *Mem;
	UWORD		Number;
	struct	tkNewMenu *OrgMenu;
};

extern struct tkMenu Menu_Main;

VOID Menu_Layout();
VOID Menu_Init();
VOID Menu_Free();

//-------------------------------------


//-------------------------------------
// Locale
//-------------------------------------
extern struct Locale *locale;

VOID loc_init(char *language);
VOID loc_free();
char *CatStr(LONG StrNum);

//-------------------------------------


//-------------------------------------
// Prefs
//-------------------------------------
#define MAX_PLAYERNAME	(20)

struct PrefWin
{
	WORD Xpos,Ypos,WinW,WinH;
	BOOL Open;
};

#define PREFSHEAD		'PREF'
#define INDSCREEN		'SCRN'
#define VERSCREEN		'1.00'
struct SetScreen
{
	ULONG					scr_width,scr_height,scr_depth,scr_mode;
	UWORD					scr_overscan;
	BOOL					scr_public;
	UBYTE					scr_pubname[MAX_PUBSCREENNAME+2];

	struct TextAttr	fontattr;
	UBYTE					fontname[MAX_FONTNAME+2];
};

#define INDGAME		'GAME'
#define VERGAME		'1.01'
struct SetGame
{
	UWORD					num_columns;
	UWORD					num_colors;
	UWORD					max_equal;
	WORD					val_order;
	WORD					display;
	UBYTE					player_name[MAX_PLAYERNAME+2];
	UBYTE					save_file[FILENAME_MAX+2];
};

#define INDWINDOW		'WIND'
#define VERWINDOW		'1.01'
struct SetWindow
{
	struct PrefWin		game;
	struct PrefWin		font;
	struct PrefWin		file;
	struct PrefWin		scrn;
	struct PrefWin		score;
	struct PrefWin		prefs;
};

struct tkPrefs
{
	struct SetScreen	scr;
	struct SetGame		game;
	struct SetWindow	win;
};

extern struct tkPrefs *prg_prefs;

void prefs_windowopen();
void prefs_windowclose();
LONG prefs_getbit();
VOID prefs_domsg();

void prefs_init();
void prefs_free();

void prefs_setscreen();
LONG prefs_askscreen();
void prefs_setfont();
LONG prefs_askfont(struct TextAttr *attr);

LONG prefs_askfile(UBYTE *title,UBYTE *filename,LONG size,LONG save);

void prefs_load();
void prefs_save();


//-------------------------------------


//-------------------------------------
// BOOPSI.c
//-------------------------------------
#include <intuition/classes.h>

#define GA_TextCol		(TAG_USER+1)
#define GA_TextJust		(TAG_USER+2)
#define GA_BoxCol			(TAG_USER+3)
#define GA_BoxBorder		(TAG_USER+4)
#define GA_Font			(TAG_USER+5)
#define GA_Symbol			(TAG_USER+6)
#define GA_Special		(TAG_USER+7)
#define GA_Integer		(TAG_USER+8)
#define GA_Float			(TAG_USER+9)

#define LV_List			(TAG_USER+101)
#define LV_Top				(TAG_USER+102)
#define LV_Show			(TAG_USER+103)
#define LV_ChangeLine	(TAG_USER+104)
#define LV_ChangeTotal	(TAG_USER+105)
#define LV_Select			(TAG_USER+106)

#define LINE_TOP			(0x80000000+1)
#define LINE_PAGEUP		(0x80000000+2)
#define LINE_UP			(0x80000000+3)
#define LINE_END			(0x80000000+4)
#define LINE_PAGEDOWN	(0x80000000+5)
#define LINE_DOWN			(0x80000000+6)
#define SHOW_SELECTED	(0x80000000+7)

enum SymbolType
{
	SYMBOL_NONE,
	SYMBOL_FILEREQUEST,
	SYMBOL_FONTREQUEST,
	SYMBOL_SCRNMODEREQUEST,
	SYMBOL_PUBSCRNREQUEST,
	SYMBOL_ARROWUP,
	SYMBOL_ARROWDOWN,
	SYMBOL_ARROWLEFT,
	SYMBOL_ARROWRIGHT,
	SYMBOL_CHECKPOINT,
};

VOID Class_Init(void);
BOOL Class_Free(void);

VOID DrawBox(struct RastPort *rp,struct DrawInfo *drinfo,ULONG x,ULONG y,ULONG w,ULONG h,BOOL Border);
LONG Txt_DimX(struct RastPort *rp,UBYTE *String,ULONG Size);
VOID Txt_PrintFit(struct RastPort *rp,UBYTE *txt,ULONG n,ULONG x,ULONG y,ULONG w,ULONG h,ULONG fg,ULONG bg,ULONG flag);

#define BOX_RIGHT		(1<<1)
#define BOX_LEFT		(1<<2)
#define BOX_CENTER	(1<<3)
#define BOX_FILL		(1<<4)

extern Class *class_button;
extern Class *class_text;
extern Class *class_symbol;

//-------------------------------------


//-------------------------------------
// Strings
//-------------------------------------

UBYTE *StrCopy(UBYTE *dest, UBYTE *src, ULONG max);
UBYTE *StrAdd(UBYTE *dest, UBYTE *src, ULONG max);

//-------------------------------------


//-------------------------------------
// File.c
//-------------------------------------
struct tkfile
{
	BPTR		file;
	BOOL		ok;
	LONG		error;
	UBYTE		*name;
};

#define ASKFILE_OVERWRITE (1<<0)
#define ASKFILE_CANTOPEN  (1<<1)

struct tkfile *file_open(STRPTR name,LONG accessmode,LONG ask);
void file_free(struct tkfile **fileptr);
void file_write(struct tkfile *file,APTR buffer,LONG size);
void file_writelong(struct tkfile *file,ULONG buf);
void file_read(struct tkfile *file,APTR buffer,LONG size);
ULONG file_readlong(struct tkfile *file);
LONG file_seek(struct tkfile *file,LONG newpos,LONG offset);
void file_saveblock(struct tkfile *file,ULONG ind,ULONG ver,ULONG size,APTR block);
void file_loadblock(struct tkfile *file,ULONG ver,ULONG size,APTR block);
void file_delete(UBYTE *name);


//-------------------------------------


//-------------------------------------
// window.c
//-------------------------------------
void window_close(struct Window *win,struct PrefWin *pref);

//-------------------------------------


//-------------------------------------
// SuperCode
//-------------------------------------
#define WHITE	(1)
#define BLACK	(2)

enum order
{
	ORDER_POS,
	ORDER_DESC,
	ORDER_RANDOM,
};

#define GAMEPLAYER		'PLAY'
#define VERGAMEPLAYER	'1.01'

struct Field
{
	ULONG				columns;
	ULONG				num_colors;
	ULONG				max_equal;
	BOOL				started;
	BOOL				finish;
	BOOL				giveup;
	WORD				val_order;
	ULONG				lines;				
	ULONG				sec_start;
	ULONG				sec_finish;
	struct tkList	try;
};

#define GAMEENTRY			'GAME'
#define VERGAMEENTRY		'1.00'

struct GameEntry
{
	struct tkNode	node;
	LONG				size;
	UBYTE				*field;
	UBYTE 			*value;
};

extern struct Field player1;

void code_init();
void code_free();

ULONG random(ULONG n);

ULONG code_getpoints(struct Field *player);
struct GameEntry *code_getnexttry(struct GameEntry *old);
struct GameEntry *code_getprevtry(struct GameEntry *old);
struct GameEntry *code_get1sttry(struct Field *player);
struct GameEntry *code_getnumtry(struct Field *player,LONG n);
struct GameEntry *code_getcombi(struct Field *player);
struct GameEntry *code_getlsttry(struct Field *player);

void code_freefield(struct Field *player);

void code_giveup(struct Field *player);
struct GameEntry *code_newfield(struct Field *player);
void code_newcomb(struct Field *player);
void code_set(struct Field *player,ULONG pos,ULONG value);
ULONG code_getfield(struct Field *player,struct GameEntry *entry,ULONG pos);
ULONG code_getvalue(struct Field *player,struct GameEntry *entry,ULONG pos);
void code_comparelast(struct Field *player);

//-------------------------------------


//-------------------------------------
// SuperCodeWindow
//-------------------------------------
enum display
{
	DISPLAY_COLORS,
	DISPLAY_LETTER,
};

void supercode_newgame();
void supercode_newplayer();
void supercode_giveup();

LONG supercode_getbit();
void supercode_domsg();
void supercode_open();
void supercode_close();
void supercode_init();
void supercode_free();

void supercode_about();

void supercode_savegame();
void supercode_loadgame();



//-------------------------------------


//-------------------------------------
// HighScores
//-------------------------------------
struct Score
{
	struct tkNode		node;
	ULONG					score;
	WORD					columns;
	WORD					colors;
	WORD					equals;
	WORD					lines;
	WORD					order;
	char					name[MAX_PLAYERNAME+2];
	struct DateStamp 		date;
	ULONG					time;
};

void score_display();
void score_add(struct Field *player,UBYTE *name);

void score_init();
void score_free();
LONG score_getbit();
VOID score_domsg();

//-------------------------------------

//*************************************




//-------------------------------------
#endif

