#include "microdot.h"

#include "ogre.h"
#include "ogre_protos.h"
#include "asyncio.h"

#define FK_OK 1
#define FK_CANCEL 2
#define FK_BASE1 10
#define FK_BASE2 30

static char *fnanames[] = { "F1", "F2", "F3", "F4", "F5", "F6", "F7", "F8", "F9", "F0" };

extern struct mdtprefs mdtprefs;

void dotermfkey( void )
{
	struct ogwin *ogw;
	struct Window *iw;
	struct IntuiMessage *im;
	int c;
	int Done = FALSE;

	ogw = ogreInitWindow( scr, 0, 0, "Funktionstastenbelegung..." );

	ogreAddGroup( ogw, 0, OGFRAME_OUTLINE, " Normal " );
	for( c = 0; c < 10; c++ )
		ogreAddString( ogw, c, 0, fnanames[ c ], FK_BASE1 + c, prefs.fkeys[ c ], 28, 128 );

	ogreAddGroup( ogw, 0, OGFRAME_OUTLINE, " Shift " );
	for( c = 0; c < 10; c++ )
		ogreAddString( ogw, c, 0, fnanames[ c ], FK_BASE2 + c, prefs.fkeys[ c + 10 ], 28, 128 );

	ogreAddGroup( ogw, 1, OGFRAME_NONE, NULL );
	ogreAddButton( ogw, 0 | OGB_ONENTER, 'o', "_OK", FK_OK );
	ogreAddHelp( ogw, 0 );
	ogreAddButton( ogw, 0 | OGB_ONESC, 'a', "_Abbruch", FK_CANCEL );

	iw = ogreOpenWindow( ogw );
	if( !iw )
		return;

	while( !Done )
	{
		im = ogreWaitIM( ogw );

		if( im->Class == IDCMP_GADGETHELP || ( im->Class == IDCMP_RAWKEY && im->Code == 0x5f ) )
			showguide( "fkeywin_gads" );
		else if( im->Class == IDCMP_GADGETUP )
		{
			switch( im->Code )
			{
				case FK_OK:
					Done = 2;
					break;
				case FK_CANCEL:
					Done = 1;
					break;

			}
		}
		ogreIMReply( ogw, im );
	}

	if( Done == 2 )
	{
		for( c = 0; c < 10; c++ )
		{
			ogreCopyStringValue( ogw, FK_BASE1 + c, prefs.fkeys[ c ] );
			ogreCopyStringValue( ogw, FK_BASE2 + c, prefs.fkeys[ c + 10 ] );
		}

	}

	ogreExitWindow( ogw );

}

#define TT_OK 1
#define TT_CANCEL 2

#define TT_IBM 3

#define TT_WHICHCOLS 5
#define TT_SETCOLS 6

static char *colopts[] = { "Normal", "Spezial", "Ansi", NULL };

void dotermterm( void )
{
	struct ogwin *ogw;
	struct Window *iw;
	struct IntuiMessage *im;
	int Done = FALSE;

	ogw = ogreInitWindow( scr, 0, 0, "Terminal..." );

	ogreAddGroup( ogw, 0, OGFRAME_OUTLINE, " Parameter " );
	ogreAddCheckbox( ogw, 0, 'i', "_IBM-Zeichensatz?", TT_IBM, ( mdtprefs.flags & MDTF_IBM ) );

	ogreAddGroup( ogw, 1, OGFRAME_OUTLINE, " Farben " );
	ogreAddCycle( ogw, 0, 'f', "_Farbe", TT_WHICHCOLS, colopts, 9, mdtprefs.whichcolors );
	ogreAddButton( ogw, 0, 's', "_Spezialfarben einstellen", TT_SETCOLS );

	ogreAddGroup( ogw, 2, OGFRAME_NONE, NULL );
	ogreAddButton( ogw, 0 | OGB_ONENTER, 'o', "_OK", TT_OK );
	ogreAddHelp( ogw, 0 );
	ogreAddButton( ogw, 0 | OGB_ONESC, 'a', "_Abbruch", TT_CANCEL );

	ogreEnable( ogw, !wbwindow, TT_WHICHCOLS, TT_SETCOLS, 0 );

	iw = ogreOpenWindow( ogw );
	if( !iw )
		return;

	while( !Done )
	{
		ogreEnable( ogw, !wbwindow && ( ogreValue( ogw, TT_WHICHCOLS ) == 1 ), TT_SETCOLS, 0 );

		im = ogreWaitIM( ogw );

		if( im->Class == IDCMP_GADGETHELP)
			showguidenum( "termterm_gads", im->Code );
		else if( im->Class == IDCMP_GADGETUP )
		{
			switch( im->Code )
			{
				case TT_OK:
					Done = 2;
					break;
				case TT_CANCEL:
					Done = 1;
					break;

				case TT_SETCOLS:
					rtPaletteRequest( "Terminal-Farben einstellen:", NULL, TAG_DONE );
					break;

				case TT_WHICHCOLS:
					if( ogreValue( ogw, TT_WHICHCOLS ) )
					{
						UBYTE tccol = mdtprefs.whichcolors;
						mdtprefs.whichcolors = ogreValue( ogw, TT_WHICHCOLS );
						term_setcolors();
						mdtprefs.whichcolors = tccol;
					}
					else
					{
						if( prefs.usecustomcolors )
							setcolors( scr );
						else
							setwbcolors( scr );
					}
					break;


			}
		}
		ogreIMReply( ogw, im );
	}

	if( Done == 2 )
	{
		if( ogreValue( ogw, TT_IBM ) )
			mdtprefs.flags |= MDTF_IBM;
		else
			mdtprefs.flags &= ~MDTF_IBM;

		mdtprefs.whichcolors = ogreValue( ogw, TT_WHICHCOLS );
		if( !wbwindow && ( mdtprefs.whichcolors == 1 ) )
			term_getcolors();
		savemdtprefs();
	}

	if( !wbwindow )
	{
		if( mdtprefs.whichcolors )
			term_setcolors();
		else
		{
			if( prefs.usecustomcolors )
				setcolors( scr );
			else
				setwbcolors( scr );
		}
	}

	ogreExitWindow( ogw );
}

#define TR_OK 1
#define TR_CANCEL 2

#define TR_DOWNPATH 3
#define TR_DOWNPATHSEL 4
#define TR_UPPATH 5
#define TR_UPPATHSEL 6

#define TR_AUTOUP 7
#define TR_AUTODOWN 8

void dotermtransfer( void )
{
	struct ogwin *ogw;
	struct Window *iw;
	struct IntuiMessage *im;
	int Done = FALSE;

	ogw = ogreInitWindow( scr, 0, 0, "Transfer..." );

	ogreAddGroup( ogw, 0, OGFRAME_OUTLINE, " Pfade " );
	ogreAddString( ogw, 0, 'p', "  Upload-_Pfad:", TR_UPPATH, prefs.term_uploadpath, 30, 128 );
	ogreAddButton( ogw, 0 | OGGP_KEEPSIZE, 'P', "?", TR_UPPATHSEL );
	ogreAddString( ogw, 1, 'l', "Down_load-Pfad:", TR_DOWNPATH, prefs.term_downloadpath, 30, 128 );
	ogreAddButton( ogw, 1 | OGGP_KEEPSIZE, 'L', "?", TR_DOWNPATHSEL );

	ogreAddGroup( ogw, 1, OGFRAME_OUTLINE, " Auto " );
	ogreAddCheckbox( ogw, 0, 'u', "_Auto-_Upload?", TR_AUTOUP, ( prefs.flags & MDF_TERM_AUTOUL ) );
	ogreAddCheckbox( ogw, 0, 'd', "_Auto-_Download?", TR_AUTODOWN, ( prefs.flags & MDF_TERM_AUTODL ) );

	ogreAddGroup( ogw, 2, OGFRAME_NONE, NULL );
	ogreAddButton( ogw, 0 | OGB_ONENTER, 'o', "_OK", TT_OK );
	ogreAddHelp( ogw, 0 );
	ogreAddButton( ogw, 0 | OGB_ONESC, 'a', "_Abbruch", TT_CANCEL );

	iw = ogreOpenWindow( ogw );
	if( !iw )
		return;

	while( !Done )
	{
		im = ogreWaitIM( ogw );

		if( im->Class == IDCMP_GADGETHELP)
			showguidenum( "termtransfer_gads", im->Code );
		else if( im->Class == IDCMP_GADGETUP )
		{
			switch( im->Code )
			{
				case TR_OK:
					Done = 2;
					break;
				case TR_CANCEL:
					Done = 1;
					break;

				case TR_UPPATHSEL:
					newdofrseldir( ogw, TR_UPPATH , "Standard-Uploadpfad:" );
					break;

				case TR_DOWNPATHSEL:
					newdofrseldir( ogw, TR_DOWNPATH , "Standard-Downloadpfad:" );
					break;
			}
		}
		ogreIMReply( ogw, im );
	}

	if( Done == 2 )
	{
		if( ogreValue( ogw, TR_AUTODOWN ) )
			prefs.flags |= MDF_TERM_AUTODL;
		else
			prefs.flags &= ~MDF_TERM_AUTODL;

		if( ogreValue( ogw, TR_AUTOUP ) )
			prefs.flags |= MDF_TERM_AUTOUL;
		else
			prefs.flags &= ~MDF_TERM_AUTOUL;

		ogreCopyStringValue( ogw, TR_UPPATH, prefs.term_uploadpath );
		ogreCopyStringValue( ogw, TR_DOWNPATH, prefs.term_downloadpath );

		rtChangeReqAttr( fr[ FR_TERMUPLOAD], RTFI_Dir, prefs.term_uploadpath, TAG_DONE );
	}

	ogreExitWindow( ogw );

}

#define DTS_LV 1
#define DTS_OK 2
#define DTS_CANCEL 3
#define DTS_DEL 4
#define DTS_NEW 5

int dotermsel( void )
{
	struct ogwin *ogw;
	struct Window *iw;
	struct IntuiMessage *im;
	int    Done = FALSE;
	struct AsyncFile *f;
	APTR tcpool;
	struct mdtprefs *list, new;
	int lvactive = -1, lastsel = -1;
	ULONG lastsecs = 0, lastmics = 0;
	char oldactivemdt[ 20 ];
	int c = 0;

	strcpy( oldactivemdt, prefs.term_currentmdt );

	tcpool = LibCreatePool( MEMF_CLEAR, 4096, 2048 );

	ogw = ogreInitWindow( scr, WFLG_RMBTRAP, 0, "Konfiguration auswählen:" );
	ogreAddGroup( ogw, 0, OGFRAME_NONE, NULL );
	ogreAddList( ogw, 0, 0xff, NULL, DTS_LV, 30, 10, 0, NULL );
	ogreLVInit( ogw, DTS_LV );

	ogreLVAddEntry( ogw, DTS_LV, "«Pointserver»", prefs.term_currentmdt[ 0 ] ? 0 : 1, NULL );
	if( !prefs.term_currentmdt[ 0 ] )
		lvactive = 0;

	pushhomedir();
	f = OpenAsync( "microdot.mdtprefs", MODE_READ, sizeof( new ) * 16 );
	if( f )
	{
		while( ReadAsync( f, &new, sizeof( new ) ) == sizeof( new ) )
		{
			list = LibAllocPooled( tcpool, sizeof( new ) );
			if( !list )
				break;
			*list = new;
			if( !stricmp( new.name, prefs.term_currentmdt ) )
			{
				ogreLVAddEntry( ogw, DTS_LV, list->name, 1, list );
				lvactive = c;
			}
			else
				ogreLVAddEntry( ogw, DTS_LV, list->name, 0, list );
			c++;
		}
		CloseAsync( f );
	}
	popdir();

	ogreAddButton( ogw, 1, 'n', "_Neu", DTS_NEW );
	ogreAddButton( ogw, 1, 'l', "_Löschen", DTS_DEL );

	ogreAddButton( ogw, 2 | OGB_ONENTER, 'o', "_Ok", DTS_OK );
	ogreAddHelp( ogw, 2 );
	ogreAddButton( ogw, 2 | OGB_ONESC, 'a', "_Abbruch", DTS_CANCEL );

	iw = ogreOpenWindow( ogw );
	if( !iw )
		return( 0 );

	while( !Done )
	{
		ogreEnable( ogw, lvactive >= 0, DTS_NEW, 0 );
		ogreEnable( ogw, lvactive > 0, DTS_DEL, 0 );

		im = ogreWaitIM( ogw );

		if( im->Class == IDCMP_GADGETHELP)
			showguidenum( "term_cfgsel_gads", im->Code );
		else if( im->Class == IDCMP_GADGETUP )
		{
			switch( im->Code )
			{
				case DTS_LV:
					lvactive = ogreValue( ogw, DTS_LV );
					if( lvactive == lastsel )
						if( DoubleClick( lastsecs, lastmics, im->Seconds, im->Micros ) )
							goto doexit;

					lastsel = lvactive;
					lastsecs = im->Seconds;
					lastmics = im->Micros;
					break;

				case DTS_OK:
doexit:
					if( lvactive >= 0 )
					{
						Done = 2;
						prefs.term_currentmdt[ 0 ] = 0;
						if( lvactive )
						{
							struct ogrevn *vn = ogreLVGetEntry( ogw, DTS_LV, lvactive );
							if( vn )
								strcpy( prefs.term_currentmdt, vn->txt );
						}
					}
					break;

				case DTS_DEL:
					if( lvactive > 0 )
					{
						ogreLVRemEntry( ogw, DTS_LV, lvactive );
						ogreLVRefresh( ogw, DTS_LV );
					}					
					break;
					
				case DTS_NEW:
					if( lvactive >= 0 )
					{
						struct ogrevn *vn = ogreLVGetEntry( ogw, DTS_LV, lvactive );

						list = LibAllocPooled( tcpool, sizeof( *list ) );
						if( list )
						{
							if( vn && vn->userdata )
								*list = * ( ( struct mdtprefs * ) vn->userdata );
							else
							{
								new = mdtprefs;
								selectmdtprefs( NULL );
								*list = mdtprefs;
								mdtprefs = new;
							}
redo:
							if( rtGetString( list->name, 19, 0, rinfo, RTGS_TextFmt, "Neue Terminalkonfiguration: Name eingeben", RTGS_Flags, GSREQF_CENTERTEXT, TAG_DONE ) )
							{
								int c;
								struct ogrevn *vn;

								for( c = 0; ; c++ )
								{
									vn = ogreLVGetEntry( ogw, DTS_LV, c );
									if( !vn )
										break;
									if( !stricmp( vn->txt, list->name ) )
									{
										askreq( "Name existiert bereits!", "Wiederholen" );
										goto redo;
									}
								}

								ogreLVAddEntry( ogw, DTS_LV, list->name, 0, list );
								ogreLVRefresh( ogw, DTS_LV );
							}
						}
					}
					break;
					
				case DTS_CANCEL:
					Done = 1;
					break;
			}
		}
	}

	if( Done == 2 )
	{
		pushhomedir();
		f = OpenAsync( "microdot.mdtprefs", MODE_WRITE, sizeof( new ) * 16 );
		if( f )
		{
			struct ogrevn *vn;
			int c;
			for( c = 1; ; c++ )
			{
				vn = ogreLVGetEntry( ogw, DTS_LV, c );
				if( !vn )
					break;
				WriteAsync( f, vn->userdata, sizeof( struct mdtprefs ) );
			}
			CloseAsync( f );
		}
		popdir();
	}

	ogreExitWindow( ogw );
	LibDeletePool( tcpool );

	return( ( Done == 2 ) && stricmp( prefs.term_currentmdt, oldactivemdt ) );
}

#define SD_OK 1
#define SD_CANCEL 2
#define SD_DEVICE 3
#define SD_UNIT 4
#define SD_BAUD 5
#define SD_RTS 6
#define SD_HS 7
#define SD_SHARED 8
#define SD_MINIT 9
#define SD_MDIAL 10
#define SD_MHANGUP 11
#define SD_DTR 14
#define SD_CARRIER 15
#define SD_7E1 16

int dotermserial( void )
{
	struct ogwin *ogw;
	struct Window *iw;
	struct IntuiMessage *im;
	int Done = FALSE;

	ogw = ogreInitWindow( scr, 0, 0, "Modem-Konfiguration..." );

	ogreAddGroup( ogw, 0 | OGGP_EXPANDSTRING, OGFRAME_OUTLINE, " Serielle Parameter " );
	ogreAddString( ogw, 0, 'd', "_Device:", SD_DEVICE, mdtprefs.device, 32, 32 );
	ogreAddInteger( ogw, 1, 0,  "  Unit:", SD_UNIT, mdtprefs.unit, 0, MAXINT, 16, 32 );
	ogreAddInteger( ogw, 1, 0, "Baud:", SD_BAUD, mdtprefs.baud, 75, MAXINT, 16, 32 );
	ogreAddCheckbox( ogw, 2, 'r', "_RTS/CTS", SD_RTS, mdtprefs.flags & 1 );
	ogreAddCheckbox( ogw, 2, 'h', "_Highspeed", SD_HS, mdtprefs.flags & 2 );
	ogreAddCheckbox( ogw, 2, 's', "_Shared", SD_SHARED, mdtprefs.flags & 4 );
	ogreAddCheckbox( ogw, 2, 'c', "_Carriercheck", SD_CARRIER, ! ( mdtprefs.flags & 8 ) );
	ogreAddCheckbox( ogw, 2, '7', "_7e1", SD_7E1 , mdtprefs.flags & 16 );

	ogreAddGroup( ogw, 1 | OGGP_EXPANDSTRING, OGFRAME_OUTLINE, " Modem-Kommandos " );
	ogreAddString( ogw, 0, 'i', "    _Init:", SD_MINIT, mdtprefs.modeminit, 32, 80 );
	ogreAddString( ogw, 1, 0,   "  Wählen:", SD_MDIAL, mdtprefs.modemdial, 32, 80 );
	ogreAddString( ogw, 2, 0,   "Auflegen:", SD_MHANGUP, mdtprefs.modemhangup, 32, 80 );
	ogreAddCheckbox( ogw, 3, 'd', "Auflegen per _DTR-Drop", SD_DTR, prefs.flags & MDTF_DROPDTR );

	ogreAddGroup( ogw, 2, OGFRAME_NONE, NULL );
	ogreAddButton( ogw, 0 | OGB_ONENTER, 'o', "_OK", SD_OK );
	ogreAddHelp( ogw, 0 );
	ogreAddButton( ogw, 0 | OGB_ONESC, 'a', "_Abbruch", SD_CANCEL );

	iw = ogreOpenWindow( ogw );
	if( !iw )
		return( 0 );

	while( !Done )
	{
		ogreEnable( ogw, !ogreValue( ogw, SD_7E1 ), SD_HS, 0 );

		im = ogreWaitIM( ogw );

		if( im->Class == IDCMP_GADGETHELP)
			showguidenum( "termserwin_gads", im->Code );
		else if( im->Class == IDCMP_GADGETUP )
		{
			switch( im->Code )
			{
				case SD_OK:
					Done = 2;
					break;
				case SD_CANCEL:
					Done = 1;
					break;

			}
		}
		ogreIMReply( ogw, im );
	}

	if( Done == 2 )
	{
		ogreCopyStringValue( ogw, SD_DEVICE, mdtprefs.device );
		ogreCopyStringValue( ogw, SD_MINIT, mdtprefs.modeminit );
		ogreCopyStringValue( ogw, SD_MDIAL, mdtprefs.modemdial );
		ogreCopyStringValue( ogw, SD_MHANGUP, mdtprefs.modemhangup );

		mdtprefs.unit    = ogreValue( ogw, SD_UNIT );
		mdtprefs.baud    = ogreValue( ogw, SD_BAUD );

		if( ogreValue( ogw, SD_RTS ) )
			mdtprefs.flags |= 1;
		else
			mdtprefs.flags &= ~1;

		if( ogreValue( ogw, SD_DTR ) )
			mdtprefs.flags |= MDTF_DROPDTR;
		else
			mdtprefs.flags &= ~MDTF_DROPDTR;

		if( ogreValue( ogw, SD_HS ) )
			mdtprefs.flags |= 2;
		else
			mdtprefs.flags &= ~2;

		if( ogreValue( ogw, SD_SHARED ) )
			mdtprefs.flags |= 4;
		else
			mdtprefs.flags &= ~4;

		if( !ogreValue( ogw, SD_CARRIER ) )
			mdtprefs.flags |= 8;
		else
			mdtprefs.flags &= ~8;

		if( ogreValue( ogw, SD_7E1 ) )
			mdtprefs.flags |= MDTF_7E1;
		else
			mdtprefs.flags &= ~MDTF_7E1;

		savemdtprefs();
	}

	ogreExitWindow( ogw );
	return( Done == 2 );
}

static struct MinList phonebooklist;
static APTR phonebookpool;

#define MDPSIZE (sizeof(struct mdphone)*2)

struct pbid {
	UWORD	id;
	UWORD	len;
};
#define PBID 0xB003

static void loadphone( void )
{
	struct AsyncFile *f;
	struct mmdphone *new;
	UBYTE  buffer[ MDPSIZE ], buffer2[ MDPSIZE ];
	struct pbid pbid;

	NewList( ( struct List * ) &phonebooklist );
	phonebookpool = LibCreatePool( MEMF_CLEAR, sizeof( struct mmdphone ) * 8, sizeof( struct mmdphone ) * 4 );

	pushhomedir();
	f = OpenAsync( "microdot.phonebook", MODE_READ, 4096 );
	popdir();
	if( !f )
		return;	

	for(;;)
	{
		if( ReadAsync( f, &pbid, sizeof( pbid ) ) != sizeof( pbid ) )
			break;
		if( pbid.id != PBID )
			break;
		ReadAsync( f, buffer, pbid.len );
		new = LibAllocPooled( phonebookpool, sizeof( *new ) );
		if( !new )
			break;
		lzw_unpack( buffer, buffer2 );
		memcpy( &new->mdp, buffer2, sizeof( struct mdphone ) );
		AddTail( ( struct List * ) &phonebooklist, ( struct Node * ) new );
	}
	CloseAsync( f );
}

static void savephone( void )
{
	struct AsyncFile *f;
	UBYTE  buffer[ MDPSIZE ];
	struct pbid pbid;
	struct mmdphone *m = ( struct mmdphone * )phonebooklist.mlh_Head;

	pushhomedir();
	f = OpenAsync( "microdot.phonebook", MODE_WRITE, 4096 );
	popdir();
	if( !f )
		return;	

	pbid.id = PBID;
	while( m->n.mln_Succ )
	{
		pbid.len = lzw_pack( &m->mdp, buffer, sizeof( struct mmdphone ), 10 );

		WriteAsync( f, &pbid, sizeof( pbid ) );
		WriteAsync( f, buffer, pbid.len );
		m = ( struct mmdphone * ) m->n.mln_Succ;
	}
	CloseAsync( f );
}

static void freephone( void )
{
	if( phonebookpool )
	{
		LibDeletePool( phonebookpool );
		phonebookpool = NULL;
	}
}

static void pb2lv( struct ogwin *ogw, ULONG id )
{
	struct mmdphone *m = ( struct mmdphone * )phonebooklist.mlh_Head;

	ogreLVInit( ogw, id );
	while( m->n.mln_Succ )
	{
		ogreLVAddEntry( ogw, id, m->mdp.name, 0, m );
		m = ( struct mmdphone * ) m->n.mln_Succ;
	}
}

#define PB_LV 1
#define PB_OK 2
#define PB_CANCEL 3
#define PB_ADD 4
#define PB_DEL 5

#define PB_NAME 6
#define PB_PHONE 7
#define PB_USERID 8
#define PB_PASSWORD 9
#define PB_SERIAL 10
#define PB_AUTOLOGIN 11


static STRPTR *tcfgtab;
static APTR tcfgpool;
static void maketcfgtab( void )
{
	int ntcfg;
	struct mdtprefs new;
	int c = 1;
	struct AsyncFile *f;

	tcfgpool = LibCreatePool( MEMF_CLEAR, 2048, 1024 );

	pushhomedir();
	ntcfg = getfilelen( "microdot.mdtprefs" );
	if( ntcfg < (long)sizeof( new ) )
	{
		popdir();
		tcfgtab = LibAllocPooled( tcfgpool, 8 );
		tcfgtab[ 0 ] = "«Pointserver»";
		return;
	}
	tcfgtab = LibAllocPooled( tcfgpool, ( ntcfg / sizeof( new ) ) * 4 + 8 );
	tcfgtab[ 0 ] = "«Pointserver»";
	f = OpenAsync( "microdot.mdtprefs", MODE_READ, sizeof( new ) * 16 );
	while( ReadAsync( f, &new, sizeof( new ) ) == sizeof( new ) )
	{
		tcfgtab[ c ] = LibAllocPooled( tcfgpool, strlen( new.name ) + 1 );
		strcpy( tcfgtab[ c++ ], new.name );
	}
	CloseAsync( f );
	popdir();
}
static void freetcfgtab( void )
{
	if( tcfgpool )
	{
		LibDeletePool( tcfgpool );
		tcfgpool = NULL;
	}
}
static int getcfgnum( char *name )
{
	char **p = tcfgtab;
	int c = 1;

	p++;
	while( *p )
	{
		if( !stricmp( name, *p++ ) )
			return( c );
		c++;
	}
	return( 0 );
}

static void showpb( struct ogwin *ogw, int which )
{
	struct mmdphone *m = ( struct mmdphone * ) GetEntry( &phonebooklist, which );

	if( !m )
		return;

	ogreSetStringValue( ogw, PB_NAME, m->mdp.name );
	ogreSetStringValue( ogw, PB_PHONE, m->mdp.phone );
	ogreSetStringValue( ogw, PB_USERID, m->mdp.username );
	ogreSetStringValue( ogw, PB_PASSWORD, m->mdp.password );
	ogreSetValue( ogw, PB_AUTOLOGIN, m->mdp.autologin );
	ogreSetValue( ogw, PB_SERIAL, getcfgnum( m->mdp.prefs ) );
}

static void donewpb( struct ogwin *ogw, struct mmdphone *cmp )
{
	struct mmdphone *new;

	new = LibAllocPooled( phonebookpool, sizeof( *new ) );
	if( !new )
		return;
	/*if( cmp )
		*new = *cmp;*/
	strcpy( new->mdp.name, "-- Neuer Eintrag --" );
	AddTail( &phonebooklist, new );
	pb2lv( ogw, PB_LV );
}

void dotermphone( void )
{
	struct ogwin *ogw;
	struct Window *iw;
	struct IntuiMessage *im;
	int    Done = FALSE;
	int lvactive = -1;
	struct ogrevn *vn;

	loadphone();
	maketcfgtab();

	ogw = ogreInitWindow( scr, WFLG_RMBTRAP, 0, "Telefonbuch" );

	ogreAddGroup( ogw, 0, OGFRAME_NONE, NULL );
	ogreAddList( ogw, 0, 0xff, NULL, PB_LV, 40, 8, 0, NULL );
	pb2lv( ogw, PB_LV );
	ogreAddButton( ogw, 1, 'n', "_Neu", PB_ADD );
	ogreAddButton( ogw, 1, 'l', "_Löschen", PB_DEL );

	ogreAddString( ogw, 2, 0, "Boxname:", PB_NAME, "", 42, 40 );
	ogreAddString( ogw, 3, 0, "Telefon:", PB_PHONE, "", 42, 128 );
	ogreAddString( ogw, 4, 0, "Username:", PB_USERID , "", 42, 80 );
	ogreAddString( ogw, 5, 0, "Passwort:", PB_PASSWORD, "", 42, 80 );

	ogreAddCycle( ogw, 6, 'k', "_Konfiguration:", PB_SERIAL, tcfgtab, 20, 0 );
	ogreAddCheckbox( ogw, 6, 't', "Automa_tischer Login?", PB_AUTOLOGIN, 0 );

	ogreAddButton( ogw, 7 | OGB_ONENTER, 'o', "_Ok", PB_OK );
	ogreAddHelp( ogw, 7 );
	ogreAddButton( ogw, 7 | OGB_ONESC, 'a', "_Abbruch", PB_CANCEL );

	iw = ogreOpenWindow( ogw );
	if( !iw )
		return;

	while( !Done )
	{
		ogreEnable( ogw, lvactive >= 0, PB_NAME, PB_PHONE, PB_USERID, PB_PASSWORD, PB_SERIAL, PB_AUTOLOGIN, 0 );

		im = ogreWaitIM( ogw );

		if( im->Class == IDCMP_GADGETHELP)
			showguidenum( "term_phone_gads", im->Code );
		else if( im->Class == IDCMP_GADGETUP )
		{
			switch( im->Code )
			{
				case PB_ADD:
					vn = NULL;
					if( lvactive >= 0 )
					{
						vn = ogreLVGetEntry( ogw, PB_LV, lvactive );
					}
					donewpb( ogw, vn ? vn->userdata : NULL);
					lvactive = GetNumEntries( &phonebooklist ) - 1;
					ogreLVSelect( ogw, PB_LV, lvactive );
					ogreLVRefresh( ogw, PB_LV );
					showpb( ogw, lvactive );
					break;

				case PB_DEL:
					if( lvactive >= 0 )
					{
						vn = ogreLVGetEntry( ogw, PB_LV, lvactive );
						Remove( ( struct Node * ) vn->userdata );
						pb2lv( ogw, PB_LV );
						ogreLVRefresh( ogw, PB_LV );
						lvactive = -1;
					}
					break;

				case PB_NAME:
					vn = ogreLVGetEntry( ogw, PB_LV, lvactive );
					if( vn )
					{
						ogreCopyStringValue( ogw, PB_NAME, ( ( struct mmdphone * ) vn->userdata ) -> mdp.name );
						ogreLVRefresh( ogw, PB_LV );
					}
					break;

				case PB_PHONE:
					vn = ogreLVGetEntry( ogw, PB_LV, lvactive );
					if( vn )
					{
						ogreCopyStringValue( ogw, PB_PHONE, ( ( struct mmdphone * ) vn->userdata ) -> mdp.phone );
					}
					break;

				case PB_USERID:
					vn = ogreLVGetEntry( ogw, PB_LV, lvactive );
					if( vn )
					{
						ogreCopyStringValue( ogw, PB_USERID, ( ( struct mmdphone * ) vn->userdata ) -> mdp.username );
					}
					break;

				case PB_PASSWORD:
					vn = ogreLVGetEntry( ogw, PB_LV, lvactive );
					if( vn )
					{
						ogreCopyStringValue( ogw, PB_PASSWORD, ( ( struct mmdphone * ) vn->userdata ) -> mdp.password );
					}
					break;

				case PB_AUTOLOGIN:
					vn = ogreLVGetEntry( ogw, PB_LV, lvactive );
					if( vn )
					{
						( ( struct mmdphone * ) vn->userdata ) -> mdp.autologin = ogreValue( ogw, PB_AUTOLOGIN ) ? 1 : 0;
					}
					break;

				case PB_SERIAL:
					vn = ogreLVGetEntry( ogw, PB_LV, lvactive );
					if( vn )
					{
						int v = ogreValue( ogw, PB_SERIAL );
						strcpy( ( ( struct mmdphone * ) vn->userdata ) -> mdp.prefs, !v ? "" : tcfgtab[ v ] );
					}
					break;

				case PB_OK:
					Done = 2;
					break;

				case PB_CANCEL:
					Done = 1;
					break;

				case PB_LV:
					lvactive = ogreValue( ogw, PB_LV );
					showpb( ogw, lvactive );
					break;
			}
		}
		ogreIMReply( ogw, im );
	}

	ogreExitWindow( ogw );

	if( Done == 2 )
		savephone();
	freephone();
	freetcfgtab();
}

struct mdphone *dotermphonesel( void )
{
	struct ogwin *ogw;
	struct Window *iw;
	struct IntuiMessage *im;
	int    Done = FALSE;
	int lvactive = -1, lastactive = -1;
	ULONG lastsecs = 0, lastmics = 0;
	struct ogrevn *vn;
	struct mmdphone *m;
	static struct mdphone mdp;

	loadphone();
	maketcfgtab();

	ogw = ogreInitWindow( scr, WFLG_RMBTRAP, 0, "Telefonbucheintrag auswählen:" );

	ogreAddGroup( ogw, 0, OGFRAME_NONE, NULL );
	ogreAddList( ogw, 0, 0xff, NULL, PB_LV, 40, 8, 0, NULL );
	pb2lv( ogw, PB_LV );
	ogreAddButton( ogw, 1 | OGB_ONENTER, 'o', "_Ok", PB_OK );
	ogreAddHelp( ogw, 1 );
	ogreAddButton( ogw, 1 | OGB_ONESC, 'a', "_Abbruch", PB_CANCEL );

	iw = ogreOpenWindow( ogw );
	if( !iw )
		return( NULL );

	while( !Done )
	{
		ogreEnable( ogw, lvactive >= 0, PB_OK, FALSE );

		im = ogreWaitIM( ogw );

		if( im->Class == IDCMP_GADGETHELP)
			showguidenum( "term_phonesel_gads", im->Code );
		else if( im->Class == IDCMP_GADGETUP )
		{
			switch( im->Code )
			{
				case PB_OK:
					Done = 2;
					break;

				case PB_CANCEL:
					Done = 1;
					break;

				case PB_LV:
					lvactive = ogreValue( ogw, PB_LV );
					if( ( lvactive >= 0 ) && ( lvactive == lastactive ) )
					{
						if( DoubleClick( lastsecs, lastmics, im->Seconds, im->Micros ) )
							Done = 2;
					}
					lastactive = lvactive;
					lastsecs = im->Seconds;
					lastmics = im->Micros;
					break;
			}
		}
		ogreIMReply( ogw, im );
	}

	vn = ogreLVGetEntry( ogw, PB_LV, lvactive );
	if( vn )	
	{
		m = vn->userdata;
		mdp = m->mdp;
	}
	else
		Done = 0;

	ogreExitWindow( ogw );

	return( Done == 2 ? &mdp : NULL );
}
